【发布时间】:2020-01-02 00:53:55
【问题描述】:
这似乎是一个简单的问题让我困惑了一段时间,所以我很感激一些建议。
我需要实现可选列表以在 WPF 中使用。由于列表可能很长,用户通常只会选择几个项目,我认为最好的方法是只获取一次完整列表,然后只列出我的主对象(MyParent)的每个实例的选定对象。 MyParent 也可以多次实例化,用户通常一次使用多个实例。我希望用户能够查看包含可能项目的整个列表并能够选择他们想要的内容。我不确定如何绑定这些属性
我的代码(简化和通用名称):
// item model:
public class MyItem
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public bool IsSelected { get; set; } = false;
}
// items factory (ideally entire list should only be
// pulled once in a program lifetime hence singleton):
public class MyItemsFactory
{
private ObservableCollection<MyItem> myItems => new ObservableCollection<MyItem>();
public static ObservableCollection<MyItem> MyItems => Instance.myItems;
private MyItemsFactory()
{
GetItems();
}
private void GetItems()
{
// generate some sample data
var i1 = new MyItem() { ItemId = 1, ItemName = "Item 1" };
var i2 = new MyItem() { ItemId = 2, ItemName = "Item 2" };
var i3 = new MyItem() { ItemId = 3, ItemName = "Item 3" };
var i4 = new MyItem() { ItemId = 4, ItemName = "Item 4" };
myItems.Add(i1);
myItems.Add(i2);
myItems.Add(i3);
myItems.Add(i4);
}
#region Singleton Implementation
private static readonly Lazy<MyItemsFactory> instance = new Lazy<MyItemsFactory>(() => new MyItemsFactory());
public static MyItemsFactory Instance => instance.Value;
#endregion
}
// parent class
public class MyParent
{
public int ParentId { get; set; }
public ObservableCollection<MyItem> MySelectedItems { get; set; } = new ObservableCollection<MyItem>();
public MyParent()
{
GetSelectedItems();
}
private void GetSelectedItems()
{
// generate some sample data
var si2 = new MyItem() { ItemId = 2, ItemName = "Item 2", IsSelected = true };
var si4 = new MyItem() { ItemId = 4, ItemName = "Item 4", IsSelected = true };
MySelectedItems.Add(si2);
MySelectedItems.Add(si4);
// how to include remaining MyItemsFactory.MyItems here?
}
}
我的用户控件:
<!-- DataContext is set to one of the instance of MyParent -->
<ListView ItemsSource="{Binding MySelectedItems}">
<ListView.View>
<GridView>
<GridViewColumn Header="Selected">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ToggleButton
IsChecked="{Binding IsSelected}"
Content="Selected"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Item Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="Selected"
IsChecked="{Binding IsSelected}"
Command="{x:Static c:CommandManager.SelectItem}"
CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
这很好用,但当然只显示 MySelectedItems。我的意图是根据 MyParent 实例的 MySelectedItems 显示所有项目(例如来自 MyItemsFactory.MyItems 的项目)。非常感谢。
【问题讨论】:
-
不太清楚你在这里问什么。您为什么要维护当前选定项目的列表?每个项目已经有一个
IsSelected属性,当用户切换按钮时会更新。只需将您的 ItemsControl ItemsSource 绑定到 MyItems 以便您看到所有这些。 -
将 ItemsSource 绑定到 MyItems,将 SelectedItems 绑定到 MySelectedItems 有什么问题?
-
通过
MyParent上的属性公开MyItemsFactory.MyItems。 -
@MarkFeldman 如果我这样做,MyParent 的每个实例都会有相同的 MyItems 列表
-
@RobinBennett 我还没有检查过。我认为它不起作用,因为 MyItems 和 MySelectedItems 中的项目指向不同的对象(例如 si2 != i2)
标签: c# wpf singleton factory observablecollection