我正在关注this answer,但是当我注释掉容器
时 <tly:MyDataGridHelper.HiddenCols>
<!-- <tly:LabelCollection> -->
<Label Name="SomeProp"/>
<Label Name="DisplayName"/>
<!--</tly:LabelCollection> -->
</tly:MyDataGridHelper.HiddenCols>
我只更改传递给RegisterAttached
public static readonly DependencyProperty HiddenColsProperty =
DependencyProperty.RegisterAttached("HiddenColsInternal", typeof(LabelCollection), typeof(MyDataGridHelper), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
var grid = (DataGrid)obj;
if (grid != null) {
var arr = ((LabelCollection)e.NewValue).Cast<Label>().ToArray();
hidden[grid.Name] = (arr ?? new Label[0]).Select(l => l.Name).ToArray();
}
}
});
但是如果我必须在getter中初始化集合
public static LabelCollection GetHiddenCols(DependencyObject obj)
{
var collection = (LabelCollection)obj.GetValue(HiddenColsProperty);
if (collection == null) {
collection = new LabelCollection();
obj.SetValue(HiddenColsProperty, collection);
}
return collection;
}
然后我的值(我的标签名称:"SomeProp
“和"DisplayName"
例如)丢失。我做错了什么?我该如何得到它们?
目前我的解决方法是保留信封<tly:LabelCollection>
(在这种情况下一切正常)
答案 0 :(得分:0)
XAML的两个版本之间存在重要差异。
虽然
<tly:MyDataGridHelper.HiddenCols>
<tly:LabelCollection>
<Label Name="SomeProp"/>
<Label Name="DisplayName"/>
</tly:LabelCollection>
</tly:MyDataGridHelper.HiddenCols>
在将新集合对象分配给HiddenCols
属性
<tly:MyDataGridHelper.HiddenCols>
<Label Name="SomeProp"/>
<Label Name="DisplayName"/>
</tly:MyDataGridHelper.HiddenCols>
只填充已经创建的集合实例,该集合实例在填充之前已分配给该属性。
但是,您的PropertyChanged回调需要已经填充的集合,因此您必须使用第一个变体。
对于第二个变体,集合类型可能实现INotifyCollectionChanged
接口,您可以附加CollectionChanged
事件处理程序。或者您稍后访问该酒店,例如在一个Loaded事件处理程序中。
答案 1 :(得分:0)
如果您想避免在XAML或getter中创建LabelCollection
,则需要使用通用ObservableCollection
作为HiddenCols
属性的属性类型。
然后用“一些”反思:
public static readonly DependencyProperty HiddenColsProperty =
DependencyProperty.RegisterAttached("HiddenColsInternal", typeof(ObservableCollection<Label>), typeof(MyDataGridHelper), new PropertyMetadata
{
DefaultValue = GetObservableCollectionDefaultValueFactory(),
PropertyChangedCallback = (obj, e) =>
{
var grid = (DataGrid)obj;
if (grid != null)
{
var arr = ((LabelCollection)e.NewValue).Cast<Label>().ToArray();
hidden[grid.Name] = (arr ?? new Label[0]).Select(l => l.Name).ToArray();
}
}
private static object GetObservableCollectionDefaultValueFactory()
{
Type type = Type.GetType("MS.Internal.ObservableCollectionDefaultValueFactory`1, WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
Type closedType = type.MakeGenericType(typeof(Label));
ConstructorInfo constructorInfo = closedType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
return constructorInfo.Invoke(null);
}
我希望它有所帮助。