Wpf组合框选择的项目不起作用

时间:2014-05-13 10:02:48

标签: wpf combobox selecteditem

我有两个对象:UserDto和RoleDto。用户拥有RoleDto属性。 在我的viewmodel中,我有以下内容:

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" />

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

请帮忙吗?

提前致谢

3 个答案:

答案 0 :(得分:6)

这是因为您RoleDTO所拥有的UserDTO引用与您设置为RoleDTOs的{​​{1}}集合中的任何Roles都不匹配ItemsSource

最好在ViewModel上定义属性,如

ComboBox

并将其设置为组合框的SelectedItem

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:0)

解决此问题的另一种方法是在Converter上使用Binding。当您使用绑定绑定SelectedItem时,WPF将检查SelectedItemItemsSource属性中所有对象的引用,当然如果没有匹配,SelectedItem将为空。使用Converter,您可以告诉WPF它应该如何匹配SelectedItem 在这种情况下,您只需在SelectedItem中找到ItemsSource并将其返回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-在Converter上使用此Binding,如下所示:

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