底层值是正确的,显示的值是ViewModelType.ToString()

时间:2013-11-04 14:20:51

标签: c# wpf data-binding combobox

这让我困惑了一段时间。我在ComboBoxHierarchicalDataTemplate(...在 UserControl 中)有一个TreeView - 事情有效,我的意思是,我可以运行一个数据库中SELECT,看到保存了正确的值。

问题是当我从数据库加载数据并将其带入视图时(抱歉,法语区域设置):

combox shows ViewModelQualifiedTypeName.ToString() as a selected value

...但下拉列表包含所有预期值,当我选择一个时,正确显示所选值:

enter image description here

当我保存更改时,我知道我做了某事

enter image description here

...但是在我重新加载数据的那一刻,一切都是A-1,顶级形状,完美......除了这个顽固的小ComboBox,它一直显示ViewModel的完全限定类型名称... < / p>

这是错误的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);
        }
    }

1 个答案:

答案 0 :(得分:1)

尝试:

 <DataTemplate DataType="{x:Type viewModels:POptionValueViewModel}">
    ......
 </DataTemplate>

编辑:SelectedValue而不是SelectedItem

  <ComboBox  
      SelectedValue="{Binding SelectedValue, Mode=TwoWay}">
        ...
  </ComboBox>