【问题标题】:WPF MVVM binding to DependencyProperty of a UserControl not workingWPF MVVM 绑定到 UserControl 的 DependencyProperty 不起作用
【发布时间】:2012-10-18 20:29:35
【问题描述】:

我正在尝试坚持使用 MVVM 方法来构建我的 WPF 应用程序,但遇到了一个奇怪的绑定问题,并且觉得我错过了一些东西。

我有一个用户控件 (PluginsTreeView),它有一个 ViewModel (PluginsViewModel) 驱动它。 PluginsTreeView 公开了一个字符串类型的公共 DependencyProperty (DocumentPath)。我的 MainWindow 在 XAML 中设置了这个属性,但它似乎没有出现在我的 UserControl 中。我正在寻找一些关于为什么这不起作用的迹象。

PluginsTreeView.xaml.cs

public partial class PluginsTreeView: UserControl
{
    public PluginsTreeView()
    {
        InitializeComponent();
        ViewModel = new ViewModels.PluginsViewModel();
        this.DataContext = ViewModel;
    }

    public static readonly DependencyProperty DocumentPathProperty =
        DependencyProperty.Register("DocumentPath", typeof(string), typeof(PluginsTreeView), new FrameworkPropertyMetadata(""));


    public string DocumentPath
    {
        get { return (string)GetValue(DocumentPathProperty); }
        set 
        {
            //*** This doesn't hit when value set from xaml, works fine when set from code behind
            MessageBox.Show("DocumentPath"); 
            SetValue(DocumentPathProperty, value); 
            ViewModel.SetDocumentPath(value);
        }
    }
    ....
 }

MainWindow.xaml

我的 PluginsTreeView 永远不会得到值“测试路径”,我不知道为什么。我觉得我在这里遗漏了一些基本的东西。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Views="clr-namespace:Mediafour.Machine.EditorWPF.Views" x:Class="Mediafour.Machine.EditorWPF.MainWindow"
    xmlns:uc="clr-namespace:Mediafour.Machine.EditorWPF.Views"
    Title="MainWindow" Height="350" Width="600">
  <Grid>
    <uc:PluginsTreeView x:Name="atv" DocumentPath="from xaml" />
  </Grid>
</Window>

但是,当我从 MainWindow 的代码隐藏设置 DependencyProperty 时,它似乎确实设置了正确的值。我试图找出这里的区别以及为什么代码隐藏方法有效而在 xaml 中设置属性不起作用。

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        MainWindowViewModel ViewModel = new MainWindowViewModel();
        this.DataContext = ViewModel;

        atv.DocumentPath = "from code behind";  //THIS WORKS!
     }
     ....
 }

搞砸了 Snoop,我看到来自 XAML“来自 xaml”的值确实进入了属性,但我在 PluginsTreeView 中的 Set 方法仍然没有被命中。除非从 MainWindow 代码隐藏中设置值,否则我作为调试工具在其中的消息框不会弹出。

【问题讨论】:

  • 我想我已经找到了我自己的问题的答案,以防其他人遇到这个问题。显然,您不应该向这些属性添加任何逻辑,因为它们仅在您从代码中设置属性时才会被调用。如果从 XAML 设置属性,则直接调用 SetValue() 方法。我最终注册了一个回调方法,现在效果很好:public static readonly DependencyProperty DocumentPathProperty = DependencyProperty.Register("DocumentPath", typeof(string), typeof(PluginsTreeView), new FrameworkPropertyMetadata("initial value", OnValueChanged));
  • 没错,您可能应该将其发布为您问题的答案。或者,也许删除您的问题,因为我确信它已经被问过并回答了好几次。

标签: wpf xaml mvvm dependency-properties


【解决方案1】:

显然您不应该向这些属性设置器添加任何逻辑,因为它们仅在您从代码设置属性时才会被调用。如果从 XAML 设置属性,则直接调用 SetValue() 方法。我最终注册了一个回调方法,现在一切正常:

public static readonly DependencyProperty DocumentPathProperty = DependencyProperty.Register("DocumentPath", typeof(string), typeof(PluginsTreeView), new FrameworkPropertyMetadata("initial value", OnValueChanged));

【讨论】:

  • 那么您是手动实现绑定的值传播吗?呜呜。
猜你喜欢
  • 2018-12-07
  • 2014-03-29
  • 2013-01-20
  • 1970-01-01
  • 2012-06-06
  • 2012-03-02
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多