因此,我尝试创建一个具有某些 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/