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);
}
如何将此组合数据绑定到我的组合框 - 我做错了什么?
首先:您的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();
此外,将combodata
从Field
(无 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);
}
}