用xaml和class设计数据

本文关键字:数据 class xaml | 更新日期: 2023-09-27 18:17:14

我有一个类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>

我可以将其用作usercontrol的设计数据。用户控件包含自定义子用户控件,当我设计父控件时,设计数据不显示在子控件中,所以我想分别向子控件添加设计数据。我的问题是,我似乎不能定义xaml只是一个集合,如

private ObservableCollection _files;

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

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

我通过声明一个不必要的类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>

有谁知道这是怎么做的吗?或者我可以摆脱不必要的类。

用xaml和class设计数据

不能在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只有一个),节省三行。