类型列表的附加属性,但没有加载标记

时间:2017-11-13 13:08:50

标签: c# wpf xaml attached-properties

我正在关注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>(在这种情况下一切正常)

2 个答案:

答案 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);
}

我希望它有所帮助。