C# 初始化XAML中的ICollection
试图做这样的事情C# 初始化XAML中的ICollection,c#,wpf,xaml,collections,C#,Wpf,Xaml,Collections,试图做这样的事情 public class MiniObject { public bool Checked { get; set; } public String Caption { get; set; } public ICollection<MiniObject> Content { get; set;} } <Window.Resources> <local:MiniObject x:Key="RootItem" Cap
public class MiniObject
{
public bool Checked { get; set; }
public String Caption { get; set; }
public ICollection<MiniObject> Content { get; set;}
}
<Window.Resources>
<local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True">
<local:MiniObject.Content>
<local:MiniObject Caption="Item1" Checked="True">
</local:MiniObject>
<local:MiniObject Caption="Item2" Checked="True">
</local:MiniObject>
</local:MiniObject.Content>
</local:MiniObject>
</Window.Resources>
在WPF中是否有这样做的方法?如果是这样的话,我是否需要改变我的对象的形状,或者我可以简单地提供一个只有WPF使用的特殊对象,比如
<Window.Resources>
<local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True">
<local:MiniObject.Content>
<local:MiniObjectCollection>
<local:MiniObject Caption="Item1" Checked="True">
</local:MiniObject>
<local:MiniObject Caption="Item2" Checked="True">
</local:MiniObject>
</local:MiniObjectCollection>
</local:MiniObject.Content>
</local:MiniObject>
</Window.Resources>
您正在尝试使用XAML的隐式集合语法。为此,属性(
Content
,在本例中)必须是实现ICollection
的类型。注意:不是ICollection
,而是实现ICollection
的类型
不能只使用接口,因为XamlReader
需要知道要创建什么类型的对象。如果你没有告诉它类型,它应该如何决定?通过搜索程序集可用的所有类型,查找实现ICollection的类型,丢弃没有无参数构造函数的类型,然后随机选择一个?没有
当您将Content
定义为List
时,XamlReader
知道它应该创建什么类型的对象。由于该类型实现了ICollection
,因此可以使用隐式集合语法。因此,它只是创建对象并调用Add
来添加子项,如果您在其中插入了一个不是MiniObject
的子项,则会出现运行时错误
您在
Content
属性中说“我需要避免使用实际实现”。在这种情况下,不能使用隐式集合语法。您将需要执行第二个示例中的操作:显式定义一个实现ICollection
的类型,并在XAML中添加一个子元素以显式创建它。仅使用上面提到的代码,在XAML中编写集合属性时将作为空引用异常抛出,原因是:
因此,如果您不想在类声明中包含集合实例,我建议按如下方式在XAML中初始化集合
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System.Collections;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True">
<local:MiniObject.Content>
<system:ArrayList> -------------------------------------1)
<local:MiniObject Caption="Item1" Checked="True">
</local:MiniObject>
<local:MiniObject Caption="Item2" Checked="True">
</local:MiniObject>
</system:ArrayList>
</local:MiniObject.Content>
</local:MiniObject>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=RootItem}, Path=Content}" DisplayMemberPath="Caption"/>
</Grid>
</Window>
public class MiniObject
{
public bool Checked { get; set; }
public String Caption { get; set; }
public IList Content { get; set; } -----------------------------------------2)
}
-------------------------------------1)
公共类小型对象
{
公共布尔检查{get;set;}
公共字符串标题{get;set;}
公共IList内容{get;set;}------------------------------------------2)
}
在第二部分中,您可能知道XAML中有四个可选的集合属性(IList、IDictionary等)。请参阅。如上所述,ICollection也可以,因为项目已添加到ArrayList
在1)中,我们还不能声明泛型类型集合,但我知道它将尽快得到支持。我也有类似的要求,并以与@NtscCobalt相同的方式实现,并得到相同的异常 此异常的一个简单解决方案是使用某个集合List或OvservableCollection初始化Content属性 这对我有用。 此外,如果使用IEnumerable而不是IList,则会出现生成错误
private IList<MiniObject> _content = new List<MiniObject>();
public IList<MiniObject> Content
{
get
{
return _content;
}
set
{
_content=value;
}
}
private IList_content=new List();
公共IList内容
{
得到
{
返回内容;
}
设置
{
_内容=价值;
}
}
用公共列表内容{get;set;}替换公共ICollection内容{get;set;}是可行的,但我需要避免使用实际的实现。使用IList也会导致同样的错误。如果不使用实际的实现,如何用数据填充集合?@John Gardner我选择ICollection的原因是因为MiniObject用于ORM,我希望它只使用IList或ICollection这样的接口。我在这里写的代码是用于设计时数据和测试的。我不希望编写一个单独的类只是为了让设计者高兴。从中,要在XAML中声明集合属性,集合类型可以是IList
、IDictionary
和Array
或实现IAddChild
,但是你的回答听起来好像ICollection
是可以的。啊,好吧,我想我理解了,这是有道理的,因为它不知道要实现什么类型的ICollection。现在我只需要弄清楚如何做我在第二个例子中解释的事情。谢谢。很有趣,很高兴知道。我不把它作为答案,主要是因为它不适合我当前的实现,我需要一个已知类型的集合(我在树视图中访问UI中对象的一些变量)。我认为在实现泛型类型集合时,这将是一个有用的特性,但目前我认为这比简单地要求为设计时/window.resources实例化使用包装器更令人困惑。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System.Collections;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True">
<local:MiniObject.Content>
<system:ArrayList> -------------------------------------1)
<local:MiniObject Caption="Item1" Checked="True">
</local:MiniObject>
<local:MiniObject Caption="Item2" Checked="True">
</local:MiniObject>
</system:ArrayList>
</local:MiniObject.Content>
</local:MiniObject>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=RootItem}, Path=Content}" DisplayMemberPath="Caption"/>
</Grid>
</Window>
public class MiniObject
{
public bool Checked { get; set; }
public String Caption { get; set; }
public IList Content { get; set; } -----------------------------------------2)
}
private IList<MiniObject> _content = new List<MiniObject>();
public IList<MiniObject> Content
{
get
{
return _content;
}
set
{
_content=value;
}
}