【问题标题】:Silverlight for Windows Phone: BindingExpression path error with user control - Property not foundSilverlight for Windows Phone:用户控件的 BindingExpression 路径错误 - 找不到属性
【发布时间】:2011-12-23 00:09:57
【问题描述】:

刚刚遇到了一个非常奇怪的数据绑定问题,我似乎无法深入了解:

场景 绑定到具有两个属性的父窗体的 MVVM 视图模型数据

    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);
        }
    }

然后我有一个具有两个依赖属性的用户控件,因此:

    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
    }
}

和用户控制 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 错误:BindingExpression 路径错误:在“ATTCookBook.ClearFilterButton”“ATTCookBook.ClearFilterButton”上找不到“ClearFilteredCategories”属性 (HashCode=126600431)。 BindingExpression: Path='ClearFilteredCategories' DataItem='ATTCookBook.ClearFilterButton' (HashCode=126600431);目标元素是 'ATTCookBook.ClearFilterButton' (Name='');目标属性是“ClearFilterAction”(类型“GalaSoft.MvvmLight.Command.RelayCommand”)..

System.Windows.Data 错误:BindingExpression 路径错误:在“ATTCookBook.ClearFilterButton”“ATTCookBook.ClearFilterButton”上找不到“ClearFilterText”属性 (HashCode=126600431)。 BindingExpression: Path='ClearFilterText' DataItem='ATTCookBook.ClearFilterButton' (HashCode=126600431);目标元素是 'ATTCookBook.ClearFilterButton' (Name='');目标属性是'ClearFilterString'(类型'System.String')..

这似乎表明视图模型正在尝试在子用户控件中查找父属性? 我不明白为什么会这样,因为我在子用户控件中设置了一个相对数据上下文以避免这种情况,并且绑定应该通过两个依赖属性。

我希望以后让用户控件更通用,但似乎无法让它以基本方式工作

快速呼叫您 Silverlight 绑定大师:D

【问题讨论】:

    标签: silverlight windows-phone-7 data-binding mvvm mvvm-light


    【解决方案1】:

    在您的 UserControl 中,您正在重置 Datacontext,所以现在是表达式

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

    与您使用 UserControl 的页面无关,而是与 UserControl 本身相关。当您想要引用在页面的 VM 上声明的通用命令而不是在绑定到模板的对象数据上时,您可能会遇到与 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; }
    
    }
    

    【讨论】:

      【解决方案2】:

      将数据上下文的分配移动到用户控件的根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">
      

      【讨论】:

        【解决方案3】:

        多亏了上面的一些,最后解决了,但是答案要简单得多。

        我所要做的就是删除所有提及的模式(删除 Mode="TwoWay")并从用户控件中删除 DataContext 设置,它就可以正常工作了。

        只是表明过度设计解决方案很容易。

        我怀疑通过添加模式设置它试图通过绑定传递数据上下文以及它抛出的内容(不是很有帮助的错误消息)

        希望这对其他人有所帮助。保持简单,然后从那里开始工作。

        对于那些感兴趣的人,我的实现基于这篇非常有用的帖子 - Silverlight UserControl Custom Property Binding

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-12
          • 2011-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-14
          • 1970-01-01
          • 2013-05-14
          相关资源
          最近更新 更多