如何将 ListView 绑定到 WPF 中单个 ViewModel 中存储的多个集合?
我有 2 个集合,我想绑定到 ListView
中的单独 GridViewColumn
:
public class EffectView : INotifyPropertyChanged
{
ObservableCollection<Effect> effects;
public ObservableCollection<Effect> Effects
{
get { return this.effects; }
set
{
this.effects = value;
this.RaisePropertyChanged ( "Effects" );
}
}
ObservableCollection<EffectDescription> descriptions;
public ObservableCollection<EffectDescription> Descriptions
{
get { return this.descriptions; }
set
{
this.descriptions = value;
this.RaisePropertyChanged ( "Descriptions" );
}
}
}
我可以这样做:
<ListView ItemsSource="{Binding EffectView.Effects}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Name}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Opacity}"
Header="Opacity" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding ?}"
Header="Description" />
</GridView>
</ListView.View>
</ListView>
但是所有内容的范围都在 EffectView.Effects
>,但我希望默认范围为 EffectView
,这样我就可以轻松地将多个集合分配给 ListView
。
比如:
<ListView ItemsSource="{Binding EffectView}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Effects Path=Name}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Effects Path=Opacity}"
Header="Opacity" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Descriptions Path=Usage}"
Header="Description" />
</GridView>
</ListView.View>
</ListView>
有什么办法可以做到这一点吗?
I have 2 collections I want to bind to a separate GridViewColumn
in a ListView
:
public class EffectView : INotifyPropertyChanged
{
ObservableCollection<Effect> effects;
public ObservableCollection<Effect> Effects
{
get { return this.effects; }
set
{
this.effects = value;
this.RaisePropertyChanged ( "Effects" );
}
}
ObservableCollection<EffectDescription> descriptions;
public ObservableCollection<EffectDescription> Descriptions
{
get { return this.descriptions; }
set
{
this.descriptions = value;
this.RaisePropertyChanged ( "Descriptions" );
}
}
}
I can do this:
<ListView ItemsSource="{Binding EffectView.Effects}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Name}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Opacity}"
Header="Opacity" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding ?}"
Header="Description" />
</GridView>
</ListView.View>
</ListView>
But then everything is scoped to EffectView.Effects
, but I want the default scope to be EffectView
so I can easily assign multiple collections to the ListView
.
Something like:
<ListView ItemsSource="{Binding EffectView}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Effects Path=Name}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Effects Path=Opacity}"
Header="Opacity" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Descriptions Path=Usage}"
Header="Description" />
</GridView>
</ListView.View>
</ListView>
Any way to accomplish this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ListView 的
ItemsSource
是其项目将出现在列表中的集合。因此,请考虑一下您要求 ListView 执行的操作:请注意第二点:每一行都必须显示 Events 集合中的某些项目和 Descriptions 集合中的某些项目。
它应该从每个项目中选择哪个项目?这两个集合中的项目之间的关系是什么?
看来您真正需要的是一个同时包含事件和描述的对象集合。然后,您可以绑定到该集合以显示两个实体的元素。大致如下:
现在您可以绑定到 EffectsAndDescriptions 集合(请注意,这假设 ListView 的 parent 的 DataContext 是
EffectView
)The
ItemsSource
of a ListView is the collection whose items will appear in the list. So think for a moment about what you're asking the ListView to do:Pay attention to that second point: every row must display some item from the Events collection and some item from the Descriptions collection.
Which item shall it pick from each? What's the relationship between the items in the two collections?
It appears that what you really need is a collection of objects that contains both an Event and a Description. You can then bind to that collection to display elements of both entities. Roughly, something like this:
Now you can bind to the EffectsAndDescriptions collection (note this assumes the DataContext of the ListView's parent is
EffectView
)这实际上是不可能的。 ItemsSource 期望传递至少实现 IEnumerable 的内容。即使您在 EffectView 上实现了 IEnumerable,您也需要将 Effect 和 EffectDescription 包装到单个对象中才能返回。
您可以将 ListView 绑定到 Effects 集合,然后使用自定义 IValueConverter 获取 Effect 并返回描述。但我不确定这是否适合您的情况。
最好的选择是包含一个包装对象(即 EffectWithDescription),其中包含您的 Effect 和 EffectDescription。然后公开 EffectWithDescription 对象的集合。不过,您需要确保这个新集合与其他集合保持同步。
That's not really possible. ItemsSource expects to be passed something that, at a minimum, implements IEnumerable. Even if you implemented IEnumerable on your EffectView, you would need to wrap Effect and EffectDescription into a single object to return.
You could bind your ListView to your Effects collection, then use a custom IValueConverter to take the Effect and return a description. But I'm not sure this would fit your situation.
Your best bet would be to include a wrapper object (i.e. EffectWithDescription) that includes both your Effect and your EffectDescription. Then expose a collection of EffectWithDescription objects. You'd need to ensure that this new collection is keep in sync with the other collections though.