我需要允许用户编辑IList<Move> moves
,其中Move
是不可变类。用户从下拉列表中选择移动(ComboBox
)。例如:
[[ for every move slot ]]
<ComboBox DisplayMemberPath="Name" ItemsSource="{DynamicResource MoveCollection}" SelectedValue="[[ move of the move slot ]]" />
[[ end for ]]
我使用ListView
来迭代集合,使用DataTemplate
来创建ComboBox
个实例,如下所示:
<ListView ItemsSource="{Binding Moves}">
<ListView.ItemTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Name" ItemsSource="{DynamicResource MoveCollection}" SelectedValue="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我得到一个例外(“双向绑定需要Path或XPath。”),所以我使用SelectedValue
的以下绑定表达式:
{Binding Path=DataContext, RelativeSource={RelativeSource Self}}
这使它编译并运行。但是,moves
集合不会在用户进行更改时更新。显然,只有数据上下文被改变,而不是实际值。
我认为这是一个问题,因为IList<Move>
被WPF简单地视为只读集合,并且对组合框值的更改不会也不能修改该集合。在代码中,WPF无法执行以下操作:
moves[x] = Resources["MoveCollection"][y];
我想更改组合框的值以更新moves
集合。我怎么能做到这一点?
答案 0 :(得分:0)
是的,您对IList的怀疑是部分正确的。让我们来看看幕后真正发生的事情: ListView是一个项目集合。对于每个项目,它会在面板模板指定的面板中创建数据模板的新副本。数据模板将作为其DataContext传递给它感兴趣的对象的引用。因此,即使您成功更改了值,基础方案在C#中也是如此:
列出yourItems = ...; foreach(yourItems中的字符串yourItem) { someControl.DataContext = yourItem;
//你在这里改变它 someControl.DataContext = yourNewItem; }
您不希望上述代码更改列表。虽然它有点不同,但我认为这里发生的事情是相似的。
我认为做你想做的最简单的方法就是做一个IList&gt;。 Wrapper只是一个包含Move的虚拟类。绑定将改变包装器上的Move。在后端,当你需要一个LINQ时,打开列表是微不足道的。
那声音怎么样?