c# - 绑定(bind)到 ViewModel 的 ObservableCollection 类型的附加属性始终返回 null

标签 c# wpf mvvm

我正在尝试绑定(bind) ObservableCollection在我的 Window给我的ViewModel使用 Attached Property .绑定(bind)似乎从 PropertyChangedCallBack 开始工作。被调用,但如果我调用 GetMyProperty方法,它总是返回 null .
MainWindow.xaml

<Window x:Class="AttachedOberservableCollectionTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AttachedOberservableCollectionTest"
        Loaded="Window_Loaded"
        Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    
    <Grid>
        <local:MainWindow.MyProperty>
            <Binding Path="MyCollection" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
        </local:MainWindow.MyProperty>
    </Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace AttachedOberservableCollectionTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public static ObservableCollection<int> GetMyProperty(DependencyObject obj)
        {
            return (ObservableCollection<int>)obj.GetValue(MyPropertyProperty);
        }

        public static void SetMyProperty(DependencyObject obj, ObservableCollection<int> value)
        {
            obj.SetValue(MyPropertyProperty, value);
        }

        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.RegisterAttached("MyProperty", typeof(ObservableCollection<int>), typeof(MainWindow), new PropertyMetadata(null, MyPopertyChanged));

        private static void MyPopertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var newCollection = (ObservableCollection<int>)e.NewValue;
            Console.WriteLine($"New collection has {newCollection.Count} values");
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var collection = GetMyProperty(this);

            if (collection == null)
                Console.WriteLine("Attached property is null");
            else
                Console.WriteLine($"Attached poperty has {collection.Count} values");
        }
    }
}
ViewModel.cs
using System.Collections.ObjectModel;

namespace AttachedOberservableCollectionTest
{
    public class ViewModel
    {
        public ObservableCollection<int> MyCollection { get; set; } = new ObservableCollection<int>();

        public ViewModel()
        {
            MyCollection.Add(1);
            MyCollection.Add(2);
        }
    }
}
我得到的输出:
New collection has 2 values
Attached property is null
Visual Studio 中的 xaml 编辑器还提供工具提示消息 The value "System.Windows.Data.Binding" is not of type "System.Int32" and cannot be used in this generic collection. Parameter name: value .

最佳答案

完全不清楚为什么要使用附加属性,而不是 MainWindow 类中的常规依赖属性。
但是,您的 XAML 在顶级 Grid 上设置附加属性,而不是 Window 对象:

<Grid>
    <local:MainWindow.MyProperty>
        <Binding Path="MyCollection" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
    </local:MainWindow.MyProperty>
</Grid>
实际上应该看起来像
<Grid local:MainWindow.MyProperty="{Binding MyCollection, Mode=TwoWay}">
</Grid>
将分配移动到 Window 实例,例如
<Window ...
    local:MainWindow.MyProperty="{Binding MyCollection, Mode=TwoWay}">
或从网格中检索属性值。

附加属性实际上应该是常规依赖属性。在 MainWindow 的 XAML 中绑定(bind)到它,如下所示:
<Window ...>
    <Window.Style>
        <Style TargetType="local:MainWindow">
            <Setter Property="MyProperty"
                    Value="{Binding MyCollection, Mode=TwoWay}"/>
        </Style>
    </Window.Style>
    ...
</Window>

关于c# - 绑定(bind)到 ViewModel 的 ObservableCollection 类型的附加属性始终返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64877889/

相关文章:

c# - 如何通过反射获取委托(delegate)类型的返回类型?

C# base() 构造函数顺序

wpf - 如何在 WPF 中的 StackPanel 的 MouseEnter 上执行命令绑定(bind)?

wpf - 创建没有虚线样式的 WPF 进度条的最简单方法是什么?

c# - 已注册服务中的 Autofac 属性注入(inject)

c# - 如何在网格单击时显示子窗口(使用 mvvm 方法)

C# 编码风格 - 行长/换行

c# - 将项目从一个列表框移动到另一个列表框

wpf - 我应该使用 AdornerLayer 来避免在屏幕外剪裁我的装饰器吗?

wpf - 如何从 ViewModel 操作 WPF 窗口控件(选项卡、文本框、列表框)