2011-11-06 56 views
2

只是擊中綁定一個非常奇怪的問題,我似乎無法到達的底部: 的MVVM查看模型數據綁定到的Silverlight:與用戶控制BindingExpression路徑錯誤 - 找不到屬性

方案

public partial class ClearFilterButton : UserControl 
{ 
    public ClearFilterButton() 
    { 
     // Required to initialize variables 
     InitializeComponent(); 
    } 

    public string ClearFilterString 
    { 
     get { return (string)GetValue(ClearFilterStringProperty); } 
     set { SetValue(ClearFilterStringProperty, value); } 
    } 

    public RelayCommand ClearFilterAction 
    { 
     get { return (RelayCommand)GetValue(ClearFilterActionProperty); } 
     set { SetValue(ClearFilterActionProperty, value); } 
    } 

    public static readonly DependencyProperty ClearFilterStringProperty = 
     DependencyProperty.Register("ClearFilterString", typeof(string), typeof(ClearFilterButton), new PropertyMetadata("", ClearFilterString_PropertyChangedCallback)); 

    public static readonly DependencyProperty ClearFilterActionProperty = 
     DependencyProperty.Register("ClearFilterAction", typeof(RelayCommand), typeof(ClearFilterButton), new PropertyMetadata(null, ClearFilterAction_PropertyChangedCallback)); 

    private static void ClearFilterString_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     //empty 
    } 

    private static void ClearFilterAction_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     //empty 
    } 
} 

和我們:具有兩個屬性

public RelayCommand ClearFilteredCategories { get; private set; } 

    /// <summary> 
    /// The <see cref="ClearFilterText" /> property's name. 
    /// </summary> 
    public const string ClearFilterTextPropertyName = "ClearFilterText"; 

    private string _clearFilterText = "Clear Filter"; 

    /// <summary> 
    /// Sets and gets the ClearFilterText property. 
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary> 
    public string ClearFilterText 
    { 
     get 
     { 
      return _clearFilterText; 
     } 

     set 
     { 
      if (_clearFilterText == value) 
      { 
       return; 
      } 

      _clearFilterText = value; 
      RaisePropertyChanged(ClearFilterTextPropertyName); 
     } 
    } 

然後我有兩個依賴性屬性的用戶的控制,從而母體形式呃控制XAML:

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP71" 
mc:Ignorable="d" 
x:Class="ATTCookBook.ClearFilterButton" 
d:DesignWidth="75" d:DesignHeight="75" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

<Grid x:Name="LayoutRoot" Background="Transparent"> 
    <Button HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{x:Null}" Width="75" Height="75"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="Click"> 
       <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding ClearFilterAction, Mode=TwoWay}"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
     <Button.Background> 
      <ImageBrush Stretch="UniformToFill" ImageSource="/icons/appbar.refresh.rest.png"/> 
     </Button.Background> 
    </Button> 
    <TextBlock HorizontalAlignment="Center" Margin="0,0,0,8" TextWrapping="Wrap" Text="{Binding ClearFilterString, Mode=TwoWay}" VerticalAlignment="Bottom" FontSize="13.333" Height="18" Width="0" d:LayoutOverrides="VerticalAlignment"/> 
</Grid> 

現在,當我將此用戶添加控件添加到主頁,並通過與用戶控制數據綁定兩個視圖模型屬性它會非常奇怪:

<local:ClearFilterButton Height="Auto" Width="Auto" ClearFilterAction="{Binding ClearFilteredCategories, Mode=TwoWay}" ClearFilterString="{Binding ClearFilterText, Mode=TwoWay}"/> 

因爲雖然上面的數據綁定語句看起來很好,但綁定錯誤與:

System.Windows.Data Error: BindingExpression path error: 'ClearFilteredCategories' property not found on 'ATTCookBook.ClearFilterButton' 'ATTCookBook.ClearFilterButton' (HashCode=126600431). BindingExpression: Path='ClearFilteredCategories' DataItem='ATTCookBook.ClearFilterButton' (HashCode=126600431); target element is 'ATTCookBook.ClearFilterButton' (Name=''); target property is 'ClearFilterAction' (type 'GalaSoft.MvvmLight.Command.RelayCommand')..

System.Windows.Data Error: BindingExpression path error: 'ClearFilterText' property not found on 'ATTCookBook.ClearFilterButton' 'ATTCookBook.ClearFilterButton' (HashCode=126600431). BindingExpression: Path='ClearFilterText' DataItem='ATTCookBook.ClearFilterButton' (HashCode=126600431); target element is 'ATTCookBook.ClearFilterButton' (Name=''); target property is 'ClearFilterString' (type 'System.String')..

這似乎表明視圖模型試圖在子用戶控件中查找父屬性? 我不明白爲什麼這可能是因爲我已經在子用戶控件中設置了一個相對數據上下文來避免這種情況,並且綁定應該通過兩個依賴屬性傳遞。

我希望讓用戶控制更通用後,但似乎無法甚至把它的基本方式工作

快速調出你Silverlight中綁定的主人:d

回答

0

最後解決了上述的一些問題,但答案要簡單得多。

我所要做的只是刪除任何提及的模式(刪除Mode =「TwoWay」),並從用戶控件中刪除DataContext設置,它就可以工作。

只是表明它很容易過度設計解決方案。

我懷疑通過將模式設置,它試圖通過綁定和它被扔了DataContext的(不是一個非常有用的錯誤消息)

希望這會幫助別人。只要保持簡單並從那裏開始工作即可。

對於那些有興趣,我是從這個非常有用的帖子基礎實施 - Silverlight UserControl Custom Property Binding

0

在你的用戶控件你重置Datacontext現在的表達式

ClearFilterAction="{Binding ClearFilteredCategories, Mode=TwoWay}" 

不是相對於您使用UserControl而是使用UserControl本身的頁面。當您想要引用在頁面的虛擬機上聲明的通用命令而不是綁定到模板的對象數據時,您可能會遇到與ItemTemplate datacontext相同的問題。

您可以使用代理:

ClearFilterAction="{Binding Source={StaticResource 
DataContextProxy},Path=DataSource.ClearFilteredCategories}" 

代理聲明爲資源:

<Resources:DataContextProxy x:Key="DataContextProxy" /> 

和DataProxy類的代碼:

public class DataContextProxy : FrameworkElement 
{ 
    public DataContextProxy() 
    { 
     this.Loaded += new RoutedEventHandler(DataContextProxy_Loaded); 
    } 

    void DataContextProxy_Loaded(object sender, RoutedEventArgs e) 
    { 
     var binding = new Binding(); 
     if (!String.IsNullOrEmpty(BindingPropertyName)) 
     { 
      binding.Path = new PropertyPath(BindingPropertyName); 
     } 
     binding.Source = this.DataContext; 
     binding.Mode = BindingMode; 
     this.SetBinding(DataContextProxy.DataSourceProperty, binding); 
    } 

    public Object DataSource 
    { 
     get { return (Object)GetValue(DataSourceProperty); } 
     set { SetValue(DataSourceProperty, value); } 
    } 

    public static readonly DependencyProperty DataSourceProperty = 
     DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null); 


    public string BindingPropertyName { get; set; } 

    public BindingMode BindingMode { get; set; } 

} 
0

移動分配的的數據上下文到usercontrol的根DataGrid

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP71" 
mc:Ignorable="d" 
x:Class="ATTCookBook.ClearFilterButton" 
d:DesignWidth="75" d:DesignHeight="75"> 

<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{Binding Parent, RelativeSource={RelativeSource Self}}" > 
    <Button HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{x:Null}" Width="75" Height="75"> 
+0

這對裝訂錯誤沒有影響,對不起 – Darkside

相關問題