DependencyProperty 和 caliburn,视图模型未按依赖关系更新 属性

DependencyProperty and caliburn, view model not updated by dependency property

我有一个包含 TreeView 的视图,称为 MbiTreeView。我想从视图模型中的(包装的)树视图中获取所选项目。

使用此自定义用户控件的 'parent' 用户控件:

<UserControl [...]>

    <views:MbiTreeView
        Grid.Row="0"
        cal:Bind.Model="{Binding TreeViewModel}"
        SelectedItem="{Binding SelectedItem}">
    </views:MbiTreeView>
</UserControl>

父用户控件绑定到此视图模型:

internal sealed class SomeViewModel : PropertyChangedBase
{
    public object SelectedItem
    {
        get => _selectedItem;
        set
        {
            _selectedItem = value;
            NotifyOfPropertyChange(() => SelectedItem);
        }
    }

    public IMbiTreeViewModel TreeViewModel { get; }

    public SomeViewModel(
        IMbiTreeViewModel treeViewModel)
    {
        TreeViewModel = treeViewModel;
    }
}

MbiTreeView 用户控件相当简单。它订阅了 selection changed 事件,并定义了一些模板(与这个问题无关,所以在问题中将它们排除在外)

<TreeView ItemsSource="{Binding Items}" SelectedItemChanged="TreeView_OnSelectedItemChanged">

iew.ItemContainerStyle>

后面的代码声明依赖属性:

public partial class MbiTreeView
{
    public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
        nameof(SelectedItem),
        typeof(object),
        typeof(MbiTreeView),
        null);

    public object SelectedItem
    {
        get => GetValue(SelectedItemProperty);
        set => SetValue(SelectedItemProperty, value);
    }

    public MbiTreeView()
    {
        InitializeComponent();
    }

    private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        SelectedItem = e.NewValue;
    }
}

当我启动应用程序时,我可以浏览树视图项。当我单击树视图节点时,OnSelectedItemChanged 事件将触发(我进入断点)。所以一切顺利,直到在依赖项中设置值 属性 SelectedItem.

然后我希望 xaml 绑定得到通知,并更新视图模型。但那永远不会发生。

我对此毫无进展,非常感谢您的帮助。

SelectedItem 绑定应该是双向的:

<views:MbiTreeView ...
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}"/>

您可以声明如下所示的 属性 以默认绑定 TwoWay。

public static readonly DependencyProperty SelectedItemProperty =
    DependencyProperty.Register(
        nameof(SelectedItem),
        typeof(object),
        typeof(MbiTreeView),
        new FrameworkPropertyMetadata(
            null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));