编辑:可以在此处找到一个示例项目。
我在主窗口内使用ListBox
,后来我绑定到ObservableCollection
。我同时使用TextBlock
和一个自定义控件,并将其绑定到集合的同一属性。我的问题是TextBlock
已正确更新,而自定义控件没有(默认构建,但其Text
属性永远不会被绑定更新)。
<ListBox Name="MyCustomItemList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding ItemText}"/>
<local:MyCustomBlock Text="{Binding ItemText}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我用Text
依赖属性作为System.Windows.Controls.Canvas
的孩子实现了MyCustomBlock
:
public class MyCustomBlock : Canvas
{
public MyCustomBlock() => Text = "<default>";
public MyCustomBlock(string text) => Text = text;
private static void TextChangedCallback(DependencyObject o,
DependencyPropertyChangedEventArgs e)
{
...
}
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
nameof(Text), typeof(string), typeof(MyCustomBlock),
new FrameworkPropertyMetadata("", TextChangedCallback));
}
最后,这是我绑定到MainWindow
构造函数中ListBox
的数据:
public class MyCustomItem
{
public MyCustomItem(string text) => ItemText = text;
public string ItemText { get; set; }
}
public MainWindow()
{
InitializeComponent();
var list = new ObservableCollection<MyCustomItem>();
list.Add(new MyCustomItem("Hello"));
list.Add(new MyCustomItem("World"));
MyCustomItemList.ItemsSource = list;
}
我是否在设置中忘记了一些东西?TextBlock.Text
如何看似正确更新但不正确,但 MyCustomBlock.Text
?
依赖关系属性可以从多个来源获取其值,因此WPF采用优先系统来确定哪个值适用。"本地"值(使用setValue或setBinding提供)将覆盖创建模板提供的任何内容。
在您的情况下,您将构造函数中的"本地"值设置(大概是打算将其作为默认值行为)。设置默认值的更好方法是在PropertyMetadata中提供。
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
nameof(Text), typeof(string), typeof(MyCustomBlock),
new FrameworkPropertyMetadata("<default>", TextChangedCallback));