我正在尝试使用附加属性
将窗口
上的ObservableCollection
绑定到ViewModel
。由于调用了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编辑器还为工具提示消息提供了值“System.Windows.Data.Binding”,该值的类型不是“System.Int32”,因此不能在此泛型集合中使用。参数名称:value
。
完全不清楚为什么要使用附加属性,而不是MainWindow类中的常规依赖属性。
但是,您的XAML在顶层网格上设置附加属性,而不是窗口对象:
<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 ...
local:MainWindow.MyProperty="{Binding MyCollection, Mode=TwoWay}">
或者从网格中检索属性值。