ObservableCollection 或 List 数据使用 MVVM 与 comboBox 绑定

本文关键字:MVVM comboBox 绑定 List 数据 ObservableCollection | 更新日期: 2023-09-27 18:18:56

我有 ObservableCollection 项目,我想将这些数据绑定到我的 comboBox。如何用组合框绑定数据?我正在使用 MVVM 模式,因此建议我如何使用 MVVM 模式绑定数据

我正在尝试执行此代码,但无法正常工作。在我的 XAML 页面中:

<ComboBox x:Name="comobo1" 
          DisplayMemberPath="CardTypeName" 
          SelectedValuePath="CardTypeID" 
          ItemsSource="{Binding Path=combodata}">    
</ComboBox>

在我的视图中模型
(Card是我的模特(

 public ObservableCollection<Card> combodata = new ObservableCollection<Card>();
 foreach (var item in App.db.States)
 {
     Card c = new Card(item.StateName, item.StateID);
     combodata.Add(c);
 }

如何将此组合数据绑定到我的组合框 - 我做错了什么?

ObservableCollection 或 List 数据使用 MVVM 与 comboBox 绑定

首先:您的combodata具有私有访问修饰符而不是公共。第二:combodata必须是属性,而不是字段。你最好将INotifyPropertyChanged的实现添加到你的类中。

您必须绑定到应实现INotifyPropertyChanged的视图模型的公共属性。

以下是您应该做的:

视图:

<ComboBox x:Name="comobo1" DisplayMemberPath="CardTypeName" SelectedValuePath="CardTypeID" ItemsSource="{Binding Path=ComboData}" />

视图模型:

public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Card> comboData;
        public event PropertyChangedEventHandler PropertyChanged;
        public ObservableCollection<Card> ComboData
        {
            get
            {
                return this.comboData;
            }
            set
            {
                if (this.comboData != value)
                {
                    this.comboData = value;
                    this.NotifyPropertyChanged("ComboData");
                }
            }
        }
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

编辑:您还需要设置视图的DataContext属性。最简单的方法是将 ViewModel 的实例影响到视图代码隐藏中的 DataContext 属性。

private ObservableCollection<Card> _combodata;
Public ObservableCollection<Card> comboData
{
   get
   {
      if (_combodata == null)
         _combodata = new ObservableCollection<Card>();
      return _combodata;
   }
   set
   {
       if (value != _combodata)
           _combodata = value;
   }
}

<ComboBox x:Name="comobo1" 
      DisplayMemberPath="CardTypeName" 
      SelectedValuePath="CardTypeID" 
      ItemsSource="{Binding Path=comboData}">    
</ComboBox>

并且不要忘记设置 DataContext 属性。

代码存在以下问题。

1.不能绑定私有字段或财产。它应该是公共财产。

2.您只提供了ItemsSource="{Binding Path=combodata}",但没有提供来源。组合数据从何而来?

ObservableCollection与任何关系无关,除非您的组合框项目在填充后不会更改。在这种情况下,列表可以很好地工作。

要使其正常工作,请将您的组合数据更改为公共属性

public ObservableCollection<Card> combodata {get;set;}

然后

<ComboBox x:Name="comobo1" 
          DisplayMemberPath="CardTypeName" 
          SelectedValuePath="CardTypeID" 
          ItemsSource="{Binding Path=combodata}" ElementName=mainWindow>    
</ComboBox>

通过指定 ElementName,您可以告诉 WPF 绑定引擎查找 mainWindow 类的 combodata 属性。

我希望这有所帮助。

我最好的猜测是您的组合框的DataContext未设置为视图模型的实例

我经常使用 Snoop 来调试应用程序的 DataContext 问题。它允许您查看可视化树,并查看所有控件的 DataContext 是什么。

数据上下文是 UI 绑定到的数据。通常,DataContext 在可视化树中设置得更高,例如在 Window 对象上,尽管作为示例,以下代码行会将 ComboBox 的 DataContext 设置为 ViewModel 的新实例,然后 ComboBox 应该能够找到要绑定到它的combodata集合。

comobo1.DataContext = new MyViewModel();

此外,将combodataField(无 get/set 访问器方法(更改为Property(有关示例,请参阅 Dmitriy 的答案(

您需要绑定到公共属性。 在您的示例中,组合数据是私有的。

正确答案是:

在 XAML 页面中":

<CollectionViewSource x:Key="comboBoxCollection" Source="{Binding comboData}"></CollectionViewSource>
  <DataTemplate x:Key="ComboBoxDataTemplate">
            <Grid MinHeight="25">
                <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                  <ComboBox x:Name="comobo1" DisplayMemberPath="CardTypeName"   SelectedValuePath="CardTypeID" ItemsSource="{Binding Source={StaticResource comboBoxCollection }}">
                    </ComboBox>
            </Grid>
         </DataTemplate>

在视图中模型:

 private ObservableCollection<Card> _combodata;
        public ObservableCollection<Card> comboData
        {
            get
            {
                if (_combodata == null)
                    _combodata = new ObservableCollection<Card>();
                return _combodata;
            }
            set
            {
                if (value != _combodata)
                    _combodata = value;
            }
        }
  if (_objCardField.FieldTag == "State") 
                {
                    cards = new Cards();
                    foreach (var item in App.db.States)
                    {
                        Card c = new Card(item.StateName, item.StateID);
                        comboData.Add(c);
                    }
                }