c# - DepencyProperty 未通过 UserControl 上的绑定(bind)进行更新

标签 c# wpf data-binding user-controls dependency-properties

因此,我尝试创建一个具有某些 DependencyProperties 的 UserControl,以便我可以重用代码。但是,某些属性未更新,而另一些属性则更新。更奇怪的是,即使对于那些正在更新的属性,“set”方法也根本没有被调用。

这是我的代码:

在 View 模型上:

public ICommand TestCommand = new DelegateCommand(x => MessageBox.Show("Ocorreu Evento"));
public List<string> TestList = new List<string> { "Hello","This","is","a","Test" };

在 View 上:

<views:CustomizedList Header="Testing"
                        Items="{Binding TestList}"/>

用户控件 View :

<StackPanel>
    <Label Content="{Binding Header}" />
    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="Hello"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

用户控制代码:

    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        set
        {
            MessageBox.Show("New header is " + value); 
            SetValue(HeaderProperty, value);
        }
    }       

    public BindingList<object> Items
    {
        get { return (BindingList<object>)GetValue(ItemsProperty); }
        set {
            SetValue(ItemsProperty, value);
            Console.WriteLine("Value was set with " + value.Count + " items.");
        }
    }

    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register("Header", typeof(string),
          typeof(ListaCustomizada));

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register("Items", typeof(BindingList<object>),
          typeof(ListaCustomizada));

标题已显示,但项目未显示。并不是说我添加了一些控制台打印来检查是否正在调用方法,但没有显示任何内容,即使对于标题也是如此。我将 UserControl 的 DataContext 设置为其本身。

有什么想法吗?

编辑:

根据@Garry Vass 的建议,我添加了一个回调函数。新代码是:

    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register("Header", typeof(string),
          typeof(ListaCustomizada), new PropertyMetadata("", ChangedCallback));

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register("Items", typeof(BindingList<object>),
          typeof(ListaCustomizada), new PropertyMetadata(new BindingList<object>(), ChangedCallback));

    private static void ChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine("Dependency property is now " + e.NewValue);
    }

这样我可以看到 Header 的值发生变化,但 Items 没有发生回调。

编辑:

将 TestList 更改为属性而不是字段,并将其类型更改为 BindingList 以与用户控件中的数据一致,结果仍然相同。

    public BindingList<object> TestList { get; set; }

    public ViewModel()
    {
        TestList = new BindingList<object> { "Hello", "This", "is", "a", "Test" };
    }

编辑: 进行更多测试后,我发现错误来自于用户控件上的 DP 绑定(bind)到 View 上的 DP,而 View 上的 DP 又绑定(bind)​​到 VM。

编辑: 终于开始工作了。搜索得更深入一点,我发现了这个link在 codeproject 完美地解释了如何创建用户控件。

最佳答案

虽然看起来可能违反直觉,但 WPF 绑定(bind)引擎基本上会忽略代码中的 setter 和 getter,并使用位于 WPF 管道深处的自己的版本。因此,您放置在那里进行干预或检查的任何代码都将不会被执行。

那么他们为什么会在那里呢?它们是编译时的助手,还为您的 Xaml 提供连接的东西。

如果您想干预或检查依赖属性发生的情况,您可以这样声明...

    #region MyProperty (DependencyProperty)
    public int MyProperty
    {
        get { return (int)GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(MainWindow),
          new PropertyMetadata(0, ChangedCallback));
    private static void ChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine("Dependency property is now " + e.NewValue);
    }
    #endregion

这声明了一个具有 Property Changed 回调的依赖属性。每当设置该属性时,WPF 就会调用它。

通过将调试器锚定在控制台语句所在的位置,您将看到回调方法中发生的更改。

关于c# - DepencyProperty 未通过 UserControl 上的绑定(bind)进行更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18021564/

相关文章:

nhibernate - 了解 Orchard 连接和数据关系

javascript - 将对象推送到 observableArray

c# - 如何在不使用第三方程序的情况下终止特定文件的进程?

c# - 为什么我的 Linq 语句被执行了两次?

c# - 结合 NotifyIcon 和 ToolTip

c# - 着眼于 future 的代码

c# - 如何在没有 XAML 的情况下将换行符插入 TextBlock?

c# - 如何将 StaticResources 传递给 MVVM 中的 ViewModel?

c# - 确定一个类是否实现了一个非常具体的接口(interface)

c# - WPF数据绑定(bind)不更新