【发布时间】:2017-10-19 14:51:32
【问题描述】:
试图留在 MVVM 道路上,我一直在为以下任务苦苦挣扎几个小时:
我想显示特定项目的字符串值(在 TextBlock 中),它是 UserCollection (ObservableCollection<Tuple<int, string>>) 的一部分。选择应通过集合中项目的 Int 属性进行,与 MyOrder 中绑定的 IdCreatedByUser-Property 匹配。
为了让事情更清楚:
一个包含 ID (int) 和 NAME (string) 的 UserCollection:
public ObservableCollection<Tuple<int, string>> UserCollection;
一个 MyOrder-Property 持有 Orders-Class 的一个实例:
public Order MyOrder;
这里是 Orders 类的示例。
public class Order: INotifyPropertyChanged
{
public string Comment;
public int IdCreatedByUser;
public bool IsComplete;
}
请注意,这只是属性的一个示例。知道这里缺少 get、set 。
我想出的唯一解决方案是像这样劫持 Combox:
<ComboBox ItemsSource="{Binding UserCollection}"
DisplayMemberPath="Item2"
SelectedValue="{Binding MyOrder.IdCreatedByUser}"
SelectedValuePath="Item1">
<ComboBox.Template>
<ControlTemplate>
<TextBlock Text="{Binding SelectedItem.Item2,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
我可以使用 ItemsSource、SelectedValue 和 SelectedValuePath 的事实使我能够选择和显示所需的项目。任何使用 TextBlocks 的解决方案? 我也在考虑一个转换器或额外的属性..但也许你可以告诉我一种以更好的方式设计它的方法.. 谢谢!
【问题讨论】:
-
在网络浏览器中,尖括号用来表示标签。因此,如果您没有在
ObservableCollection<Tuple<int, string>>周围加上反引号以通知该降价它将按字面意思显示,它会显示为“ObservableCollection>”,这不是您想要的。 -
也就是说,您的问题解决方案很好。我昨天在生产代码中做了同样的事情。您可以改为write a MultiConverter 并将其与多重绑定一起使用,但它不会那么冗长。您可以在绑定中索引集合,但只能使用文字索引值:
{Binding MyColl[1].Foo}等。 -
另一个选项是给你的视图模型一个
SelectedUser属性,当MyOrder或MyOrder.IdCreatedByUser改变时返回UserCollection[MyOrder.IdCreatedByUser]并引发PropertyChanged("SelectedUser")。 -
这也是一个不错的方法。这里的问题是我有更多的控件来向我显示特定用户的名称..比如 Orders-Class 中的属性 IdFinishedByUser、IdEditedByUser 等等。所以我必须在我的 Viewmodel 中处理更多属性,我想防止这种情况发生。我的 ComboBox 劫持是否有任何关于 TextBlocks 的正常使用的问题?
-
我认为它不会有任何问题。我会考虑的一件事是编写一个 ComboBox 样式来简化 XAML,如果你正在做一堆这样的事情。我会把昨天做的删掉然后贴出来。