C# MVVM Combobox

本文关键字:Combobox MVVM | 更新日期: 2023-09-27 17:57:35

在XAML中,我有一个组合框定义为:

<ComboBox x:Name="UsernameComboBox" 
          ItemsSource="{Binding Users}" 
          DisplayMemberPath="Username" 
          SelectedItem="{Binding Path=SelectedName, Mode=TwoWay}"/>

目前,它不显示任何默认的选定项目。

我在组合框中填写了一个列表:

public List<User> Users
{
    get
    {
        return _userRepository.RetrieveUsers();
    }
}
public List<User> RetrieveUsers()
{
    _users = (from Users in _db.Users select Users).ToList();
    return _users;
}

正确的用户是组合框的ItemSource。然后在XAML中,我定义了SelectedItem,并将其绑定到名为Selectedname的属性。

在代码中,这看起来像:

    private User _selectedName;
    public User SelectedName
    {
        get
        {
            return _selectedName;
        }
        set 
        {
            if (_selectedName == value) return;
            _selectedName = value;
            OnPropertyChanged("SelectedName");
        }
    }

如何使我的组合框在启动时显示selectedItem?

C# MVVM Combobox

我可以看到的一个问题是,每次访问Users属性时,都会调用RetrieveUsers()方法来重新运行数据库查询。这将打乱您的SelectedItem绑定,它将期望绑定到ComboBox的项目列表保持不变。换句话说,它通过评估SelectedItem与绑定项的集合的相等性来找到所选项。

您需要查询数据库一次。。。

public YourClassConstructor()
{
   _users = _userRepository.RetrieveUsers();
   _selectedName = _users[0];
}
public List<User> Users
{
    get
    {
        return _users;
    }
}

这也将确保第一个项目被选中。

在选择绑定到不可观察的集合时,应该考虑一些性能影响。如果绑定到可观察的集合而不是简单的列表,则更新时间会明显加快。

您应该考虑使用实现INotifyCollectionChanged接口的项源,例如ObservableCollection{T}集合,或者使用ICollectionView在视图模型中公开您的项源。还可以在MVVM的上下文中查看有关数据绑定的信息。

我个人更喜欢使用ICollectionView在视图模型中公开项目源。Silverlight提供PagedCollectionView类,WPF提供ListCollectionView类。

public ICollectionView Users
{
    get
    {
        if (_viewModelUsers == null)
        {
            _viewModelUsers = new PagedCollectionView(_viewModelUsersSource);
        }
        return _viewModelUsers;
    }
}
private ICollectionView _viewModelUsers;
private ObservableCollection<User> _viewModelUsersSource = new ObservableCollection<User>();

然后,在使用对存储库的调用填充基础源集合之后,可以使用MoveCurrentToFirst()来设置所选项目。