WPF:DependencyProperty在TextBlock上起作用,但在自定义控件上无效



编辑:可以在此处找到一个示例项目。

我在主窗口内使用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));

最新更新