与xaml和类的Designdata

时间:2011-12-09 15:38:42

标签: c# wpf xaml

我有一个ComponentItem类,我简化了(伪代码)

public class ComponentItem : NotificationObject
{
    private ObservableCollection<FileItem> _files;
    public ObservableCollection<FileItem> Files

    private ObservableCollection<SparepartItem> spareparts;
    public ObservableCollection<SparepartItem> SpareParts
    public string ObjectId
}

如果我为这个类创建设计数据,我可以通过

来完成
<m:ComponentItem xmlns:m="clr-namespace:AITReportEditor.Infrastructure.Models;assembly=AITReportEditor.Infrastructure" ObjectId="AAAA-BBBB-CCCC-DDDDD">
    <m:ComponentItem.PartData>
        <m:PartDataItem Name="Component name" Status="1" Note="This is a note description"  />   
    </m:ComponentItem.PartData>
    <m:ComponentItem.Files>
        <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" ></m:FileItem>
        <m:FileItem FileName="Image1.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" ></m:FileItem>
    </m:ComponentItem.Files>
    <m:ComponentItem.SpareParts>
        <m:SparepartItem ObjectId="AAAA-BBBB-CCCC-DDDDD" Note="This is a note1" SpId="1" Amount="22" />
        <m:SparepartItem ObjectId="AAAA-BBBB-CCCC-DDDDE" Note="This is a note2" SpId="1" Amount="23" />
    </m:ComponentItem.SpareParts>
</m:ComponentItem>

我可以将它用作usercontro的设计数据。用户控件包含自定义子用户控件,当我设计父控件时,设计数据不显示在子控件中,因此我想单独向子控件添加设计数据。我的问题是我似乎无法为像

这样的集合定义xaml

私人ObservableCollection _files;

似乎没有办法声明像伪xaml代码

<List<FileItem>  ............
 <m:FileItem ...... />

我通过声明一个unessesary类FilesItem

解决了这个问题
 public class FilesItem : ObservableCollection<FileItem>
    {
        public FilesItem()
        {

        }
    }
}

和xaml文件。

<m:FilesItem xmlns:m="clr-namespace:AITReportEditor.Infrastructure.Models;assembly=AITReportEditor.Infrastructure">
    <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" ></m:FileItem>
    <m:FileItem FileName="Image2.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" ></m:FileItem>
    <m:FileItem FileName="Image2.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDF" ></m:FileItem>
</m:FilesItem>

任何人都知道这是否是这样做的方式,或者我可以以某种方式摆脱unessesary类。

1 个答案:

答案 0 :(得分:2)

您无法在XAML中创建通用实例(至少在已编译的XAML中),一种解决方法是您所显示的子类化。另一种方法是将创建委托给标记扩展,如下所示:

[ContentProperty("Items")]
public class GenericCollectionFactoryExtension : MarkupExtension
{
    public Type Type { get; set; }

    private readonly List<Type> _TypeArguments = new List<Type>();
    public List<Type> TypeArguments { get { return _TypeArguments; } }

    private readonly List<Object> _Items = new List<Object>();
    public List<Object> Items { get { return _Items; } }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var genericType = Type.MakeGenericType(_TypeArguments.ToArray());
        var list = Activator.CreateInstance(genericType) as IList;
        if (list == null) throw new Exception("Instance type does not implement IList");
        foreach (var item in Items)
        {
            list.Add(item);
        }
        return list;
    }
}

这会使用反射创建泛型集合,添加传递给它的所有项目(此处假定将创建IList以使其更容易)并返回集合。

用法:

xmlns:om="clr-namespace:System.Collections.ObjectModel;assembly=System"
<me:GenericCollectionFactory x:Key="files"
                Type="{x:Type om:ObservableCollection`1}">
    <me:GenericCollectionFactory.TypeArguments>
        <x:Type Type="m:FileItem" />
    </me:GenericCollectionFactory.TypeArguments>
    <m:FileItem FileName="Image1.jpg" Note="This is a note1" ObjectId="AAAA-BBBB-CCCC-DDDDD" />
    <m:FileItem FileName="Image1.jpg" Note="This is a note2" ObjectId="AAAA-BBBB-CCCC-DDDDE" />
</me:GenericCollectionFactory>
<!-- ... -->
<m:ComponentItem Files="{StaticResource files}"/>

`1是指定此类型是通用的必要条件。你可以通过创建一个只需要一个类型参数的版本来减少XAML(因为ObservableCollection只有一个类只有一个),节省了三行。