【问题标题】:WPF - Binding to custom UserControl's DependencyProperty doesn't workWPF - 绑定到自定义 UserControl 的 DependencyProperty 不起作用
【发布时间】:2018-12-07 13:24:55
【问题描述】:

我目前正在开发一个使用 Window(带有我的 ViewModel)和我自己的 UserControl 的 MVVM 项目。 .xaml 文件中的 UserControl 几乎是空的,因为它的所有功能都来自代码隐藏,它绘制不同的形状。我想将 ViewModel 中的属性绑定到 UserControl 中的 DependencyProperty,但无论我做什么,我都无法让它工作。我在这里和不同的网站上阅读了大量的答案,并注意到它可能与 UserControl 的 DataContext 相关,但我最终还是没能解决这个问题。我在 ViewModel 中引发 PropertyChanged 事件的方式是正确的。我可以成功地将我的属性绑定到其他控件(如 TextBoxes 等),但不能绑定到我的控件。如果您能向我解释为什么它不起作用以及如何解决这个问题,我将不胜感激。问候!

MainWindow.xaml 绑定:

<Grid Margin="10">
    <local:FretboardControl Grid.Row="0" Fretboard="{Binding CurrentFretboard, Mode=TwoWay}"/>
</Grid>

FretboardControl.xaml:

<UserControl ...>
    <Grid>
<TextBlock Text="{Binding Path=Fretboard, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:FretboardControl}}"/>
    //the TextBlock above is just a test
    <Canvas.../>
    </Grid>
</UserControl>

FretboardControl.xaml.cs(代码隐藏):

public static readonly DependencyProperty FretboardProperty = DependencyProperty.Register
    (nameof(Fretboard), typeof(Fretboard), typeof(FretboardControl), new PropertyMetadata(new Fretboard(), PropertyChangedCallback));

public Fretboard Fretboard {
    get {
        return GetValue(FretboardProperty) as Fretboard;
    }
    set {
        SetValue(FretboardProperty, value);
    }
}

protected static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e) {
    //breakpoint here. It is reached only once during runtime:
    //at start, when the default value is inserted
    if (o is FretboardControl) {
        (o as FretboardControl).RefreshFretboard();
    }
}

【问题讨论】:

  • UserControl 的构造函数中没有类似DataContext = this; 的东西吗?也就是说,AncestorType=UserControl 应该没问题(而不是 local:FretboardControl)。
  • 请注意,if (o is FretboardControl) 后跟 (o as FretboardControl) 是没有意义的。只需致电((FretboardControl)o).RefreshFretboard()。如果调用 PropertyChangedCallback,这通常表明该属性被设置为默认值以外的值。所以你的 Binding 可能已经奏效了......
  • @Clemens 绑定的属性 (CurrentFretboard) 在运行时发生变化(可以使用 ListBox 选择)。尽管属性正确更改,但 PropertyChangedCallback 从未被调用,因此控件和窗口之间的绑定似乎不起作用。将 DataContext 更改为 self (在构造函数中,如您建议的那样或在 XAML 中)并没有太大变化。启动时不会调用 PropertyChangedCallback,但绑定仍然不起作用。
  • 我没有建议设置DataContext,只是问了一下。 UserControl 永远不应设置自己的 DataContext。无论是在 XAML 中还是在后面的代码中。
  • 啊,对不起。所以不,它目前没有以任何方式设置。

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


【解决方案1】:

好的,显然我可能找到了问题的根源。我的 CurrentFretboard 设置器引发了 PropertyChanged 事件,但我没有更改对象本身的引用。对象被修改了,但它仍然是同一个对象。我认为这无关紧要,无论如何它都会被发送到绑定,但看起来只有在更改引用时才会调用 PropertyChangedCallback。我想我可以替换每个集合上的引用,或者只收听 UserControl 中已经存在的 PropertyChanged 事件。感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 2013-06-03
    • 2020-06-16
    • 2012-06-06
    • 1970-01-01
    相关资源
    最近更新 更多