【问题标题】:Wpf combobox selected item not workingWpf组合框所选项目不起作用
【发布时间】:2014-05-13 10:02:47
【问题描述】:

我有两个对象:UserDto 和 RoleDto。用户有一个属性,即 RoleDto。 在我的视图模型中,我有以下内容:

public UserDto User
    {
        get { return _user; }
        set
        {
            if (_user == value) return;

            _user = value;
            User.PropertyChanged += UserPropertyChanged;
            OnPropertyChanged("User");
        }
    }
    private UserDto _user;

public IEnumerable<RoleDto> Roles { get; set; } //I load all available roles in here

在视图中,我要选择用户所属的角色。这就是我在视图中定义组合框的方式:

<ComboBox Grid.Row="3" Grid.Column="1" Margin="5" ItemsSource="{Binding Roles}" SelectedItem="{Binding User.Role, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Description" />

如果我尝试创建一个新用户并从组合框中选择一个角色,它会正确绑定到该用户。问题是当我加载一个已经存在的用户时,该角色不会显示在组合框中(即使用户已经定义了角色)。

有什么帮助吗?

提前致谢

【问题讨论】:

  • 我推断什么,当您(userdto)用户有数据或没有您的组合框绑定到 Roles 时。您必须指定组合框 selectedItem。

标签: wpf combobox selecteditem


【解决方案1】:

这是因为您的UserDTO 拥有的RoleDTO 的引用与您设置为ComboBoxItemsSourceRoles 集合中的任何RoleDTOs 不匹配。

最好在 ViewModel 上定义一个属性,例如

    public RoleDTO SelectedRole
    {
        get { return Roles.FirstOrDefault(role => role.Role == User.RoleDto.Role); }
        set { User.RoleDto = value; OnPropertyChanged("SelectedRole"); }
    }

并将其设置为您的组合框的 SelectedItem

ItemsSource="{Binding Roles}" SelectedItem="{Binding SelectedRole, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Description" />

【讨论】:

    【解决方案2】:

    在我看来,此页面上的第二个选项是最简单的方法。

    https://rachel53461.wordpress.com/2011/08/20/comboboxs-selecteditem-not-displaying/

    您可以覆盖对象上的 equals 属性,以便在项目具有相同数据时返回 true。然后,当组合框框检查以确保您的项目在选择中时,它将找到匹配项。

    【讨论】:

      【解决方案3】:

      解决此问题的另一种方法是在Binding 上使用Converter。当您使用绑定绑定SelectedItem 时,WPF 将针对ItemsSource 属性内的所有对象检查SelectedItem 的引用,当然如果没有匹配,SelectedItem 将为空。使用 Converter 你可以告诉 WPF 它应该如何匹配 SelectedItem
      在这种情况下,您只需在ItemsSource 中找到SelectedItem 并将其返回给Binding。所以请按照以下步骤操作:
      1- 创建一个类并实现IValueConverter。它有两种方法:ConvertConvertBack
      2-对于Convert 方法做这样的事情:

      public class MySelecteItemBindingConverter : IValueConverter
      {
          public object Convert(object value, Type targetType, 
              object parameter, CultureInfo culture)
          {
              var mySelectedItem = value as MySelectedItemType;
              var myItemsSource = parameter as List<MySelectedItemType>;
              var matchedItem = myItemsSource.FirstOrDefault(i=>i.Id == mySelectedItem.Id);
              return matchedItem;
          }
      
          public object ConvertBack(object value, Type targetType, 
              object parameter, CultureInfo culture)
          {
              // Do just like Convert method
          }
      }
      

      3- 在您的 Binding 上使用此 Converter,如下所示:

      var myBinding = new Binding("YourBindingPath");
      myBinding.Converter = new MySelectedItemBindingConverter();
      myBinding.ConverterParameter = myItemsSource; //this is List<MySelectedItemType> in this example
      myCombo.SetBinding(ComboBox.SelectedItemProperty, myBinding);
      

      注意:如果您想从XAML 进行绑定,则不能像这样传递ConverterParameter,而是应该创建一个static 列表并将其用作ItemsSource 或使用MultiBinding 使用技巧传递您的 ConverterParameter。这里有一个很好的简单解释:Binding ConverterParameter

      【讨论】:

      • 为什么要投反对票?!如果您有真正的理由投反对票,请分享。 tnx
      猜你喜欢
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多