DepencyProperty没有从UserControl上的绑定更新

时间:2013-08-02 16:10:28

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

所以,我正在尝试使用一些DependencyProperties创建一个UserControl,以便我可以重用代码。但是,有些属性没有更新,而其他属性则没有。甚至更奇怪的是,即使对于那些正在更新的属性,也没有调用方法“set”。

这是我的代码:

在ViewModel上:

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

在视图上:

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

用户控制视图:

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

标题显示,但项目不显示。不是我添加了一些控制台打印来检查是否正在调用这些方法,但是没有任何内容显示,即使对于Header也是如此。我将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 ont eh usercontrol绑定到视图上的DP的事实,该视频绑定到VM。

修改 终于搞定了。更深入地搜索我在codeproject找到了这个link,它完美地解释了如何创建用户控件。

1 个答案:

答案 0 :(得分:2)

虽然看似违反直觉,但WPF绑定引擎基本上忽略了代码中的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回调的Dependency Property。只要设置了属性,WPF就会调用它。

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