我有一个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类。
答案 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
只有一个类只有一个),节省了三行。