这让我困惑了一段时间。我有一个ComboBox
in a HierarchicalDataTemplate
, in a TreeView
(...in a UserControl ) - 事情有效,我的意思是,我可以SELECT
在数据库中运行 a 并查看是否保存了正确的值。
问题是当我从数据库加载数据并将其显示在视图中时(对不起,法语语言环境):
...但是下拉列表包含所有预期值,当我选择一个时,所选值会正确显示:
当我再次保存更改时,我知道我做对了:
......但是当我重新加载数据的那一刻,一切都是 A-1,顶级形状,完美......除了这个顽固的小 ComboBox 不断显示 ViewModel 的完全限定类型名称......
这是有缺陷的 ComboBox 的标记 - 老实说,我认为它没有任何问题:
<ComboBox Style="{StaticResource StdDropdown}"
IsEditable="True"
TextSearch.TextPath="Value"
ItemsSource="{Binding SelectedOption.Values}"
SelectedItem="{Binding SelectedValue, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="viewModels:POptionValueViewModel">
<Border Style="{StaticResource ListItemBorder}">
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource DropdownLabel}"
Content="{Binding Value}" />
</StackPanel>
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我需要知道这是怎么可能的(以及,如何解决它!)。我的意思是,并不是整个列表都显示 ViewModel.ToString()...
解决方案是绑定SelectedValue
而不是SelectedItem
:
<ComboBox Style="{StaticResource StdDropdown}"
IsEditable="True"
TextSearch.TextPath="Value"
ItemsSource="{Binding SelectedOption.Values}"
SelectedValue="{Binding SelectedValue, Mode=TwoWay}">
为了完整起见(如果它可以帮助理解为什么一个工作而不是另一个工作) - 正在显示的 ViewModel:
/// <summary>
/// Encapsulates a <see cref="IPOptionValue"/> implementation for presentation purposes.
/// </summary>
[ComVisible(false)]
public class POptionValueViewModel : ViewModelBase<IPOptionValue>
{
public POptionValueViewModel(IPOptionValue entity) : base(entity) { }
public string OptionName { get { return Entity.POptionName; } }
/// <summary>
/// Gets a number representing the sorting order for the P-Option value.
/// </summary>
/// <value>
/// The sort order.
/// </value>
public int SortOrder { get { return Entity.SortOrder; } }
/// <summary>
/// Gets the P-Option value.
/// </summary>
/// <value>
/// The value.
/// </value>
public string Value { get { return Entity.Value.Trim(); } }
public override bool IsNew
{
get { return false; }
}
}
...以及 TreeView 项的 ViewModel 属性:
public POptionValueViewModel SelectedValue
{
get
{
var result = SelectedOption == null
? null
: SelectedOption.Values.SingleOrDefault(e => e.Value == Entity.POptionValue.Trim());
return result;
}
set
{
var selectedOption = _parentGroupOptions.SingleOrDefault(option => option.Name == value.OptionName);
if (selectedOption == null) return;
var selectedValue = selectedOption.Values.SingleOrDefault(option => option.Value.Trim() == value.Value.Trim());
if (selectedValue == null) return;
Entity.POptionValue = selectedValue.Value.Trim();
NotifyPropertyChanged(() => SelectedValue);
}
}