【问题标题】:C# MVVM ComboboxC# MVVM 组合框
【发布时间】:2011-09-01 20:29:26
【问题描述】:

在 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 并将其绑定到一个名为 Selected name 的属性。

在代码中是这样的:

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

如何让我的组合框在启动时显示一个 selectedItem?

【问题讨论】:

    标签: c# mvvm binding combobox selecteditem


    【解决方案1】:

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

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

    我个人更喜欢使用 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() 在使用对您的存储库的调用填充基础源集合后设置选定项。

    【讨论】:

    • 集合没有改变,所以这不相关。
    【解决方案2】:

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

    你需要查询一次数据库...

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

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

    【讨论】:

    • 谢谢。确实很好的答案。我特别感谢您指出我一直在查询数据库。至少对于这个应用程序来说,它是非常不需要的。我还将看到它如何使用“静态”列表影响组合框。再次感谢。
    • 没问题 - 如果这对您有帮助,请点赞并标记为答案。
    • 这有点极端! - 无论如何,很高兴它有帮助!
    猜你喜欢
    • 2018-06-12
    • 2021-09-16
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2011-06-13
    • 2014-03-30
    相关资源
    最近更新 更多