WPF MVVM绑定UserControl的DependencyProperty无法工作

5

我试图遵循MVVM方法构建我的WPF应用程序,并遇到了一些奇怪的绑定问题,感觉自己遗漏了一些东西。

我有一个用户控件(PluginsTreeView),它有一个驱动它的ViewModel(PluginsViewModel)。PluginsTreeView公开了一个类型为字符串的public 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从来没有得到过“test path”这个值,我不确定为什么。我感觉我可能漏掉了一些基本的东西。

<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中的值“from xaml”确实传递到属性中,但我的PluginsTreeView中的Set方法仍然没有被执行。我在那里放置了一个调试工具用的消息框,除非从MainWindow代码后台设置值,否则该消息框不会弹出。

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

2

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

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

那么你是手动实现绑定的值传递吗?哎呀。 - Grault

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接