C# WPF将组合框绑定到我的ViewModel
我正在尝试将ViewModel绑定到组合框。我有如下定义的ViewModel类:C# WPF将组合框绑定到我的ViewModel,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在尝试将ViewModel绑定到组合框。我有如下定义的ViewModel类: class ViewModel { public ViewModel() { this.Car= "VW"; } public string Car{ get; set; } } 我在Window_Load中将此ViewModel设置为DataContext,如下所示: private void Window_Loaded(object sender, Ro
class ViewModel
{
public ViewModel()
{
this.Car= "VW";
}
public string Car{ get; set; }
}
我在Window_Load中将此ViewModel设置为DataContext,如下所示:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new CarModel();
}
然后在我的xaml中,我这样做是为了将我的组合框绑定到这个ViewModel。我想在我的组合框中显示默认选中的“VW”:
<ComboBox Name="cbCar" SelectedItem="{Binding Car, UpdateSourceTrigger=PropertyChanged}">
<ComboBoxItem Tag="Mazda">Mazda</ComboBoxItem>
<ComboBoxItem Tag="VW">VW</ComboBoxItem>
<ComboBoxItem Tag="Audi">Audi</ComboBoxItem>
</ComboBox>
马自达
大众汽车
奥迪
我有两个问题:
namespace MyData
{
class ViewModel
{
public ViewModel()
{
this.Make = "";
this.Year = 1;
this.DefaultCar = "VW"; //this is where I get error 'No string allowed'
}
public IEnumerable<Car> Cars
{
get
{
var cars = new Car[] { new Car{Model="Mazda"}, new Car{Model="VW"}, new Car{Model="Audi"} };
DefaultCar = cars.FirstOrDefault(car => car.Model == "VW");
}
}
public string Make { get; set; }
public int Year { get; set; }
public Car DefaultCar { get; set; }
}
class Car
{
public string Model { get; set; }
}
}
名称空间MyData
{
类视图模型
{
公共视图模型()
{
这个。Make=“”;
本年=1年;
this.DefaultCar=“VW”//这就是我得到错误“不允许字符串”的地方
}
公车
{
得到
{
var cars=新车[]{new Car{Model=“Mazda”},新车{Model=“VW”},新车{Model=“Audi”};
DefaultCar=cars.FirstOrDefault(car=>car.Model==“VW”);
}
}
公共字符串Make{get;set;}
公共整数年{get;set;}
公共汽车默认汽车{get;set;}
}
班车
{
公共字符串模型{get;set;}
}
}
viewModel.Car=“VW”
,则它应该在组合框中自动选择该项。
为此,您需要在设置DataContext
之前实现INotifyPropertyChanged
或设置Car
class ViewModel : INotifyPropertyChanged
{
private string car;
public ViewModel()
{
this.Car = "VW";
this.Cars = new ObservableCollection<string>() { "Mazda", "VW", "Audi" };
}
public string Car
{
get
{
return this.car;
}
set
{
if (this.car != value)
{
this.car = value;
OnPropertyChanged();
}
}
}
public ObservableCollection<string> Cars { get; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
如果源代码或视图比仅显示字符串更复杂,则还可以设置ComboBox.ItemTemplate
:
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
在视图模型中,只需添加一个列表属性:
public ObservableCollection<string> Cars { get; set; }
公共可观测收集车{get;set;}
它不一定非得是
ObservableCollection
,但只要您更改集合,该类型将自动更新UI。当您要实现MVVM时,如果您开始考虑在应用程序中用对象来表示汽车,那会好得多:
public class ViewModel
{
public Car SelectedCar{ get; set; }
public ObservableCollection<Car> Cars{
get {
var cars = new ObservableCollection(YOUR_DATA_STORE.Cars.ToList());
SelectedCar = cars.FirstOrDefault(car=>car.Model == "VW");
return cars;
}
}
}
public class Car
{
public string Model {get;set;}
public string Make { get; set; }
public int Year { get; set; }
}
公共类视图模型
{
公共汽车选定汽车{get;set;}
公共可观测收集车{
得到{
var cars=新的ObservableCollection(您的_DATA_STORE.cars.ToList());
SelectedCar=cars.first或default(car=>car.Model==“VW”);
返回车辆;
}
}
}
公车
{
公共字符串模型{get;set;}
公共字符串Make{get;set;}
公共整数年{get;set;}
}
您的Xaml:
<ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}"
UpdateSourceTrigger=PropertyChanged}"/>
谢谢。你会怎么重写这行,我不明白它在做什么,因为“车”没有定义“SelectedCar=cars.FirstOrDefault(car=>car.Model==VW”);”?Thansk,@dbnex14,car变量表示cars集合中的每个项,之前不需要定义它。看看syntaxis汽车=>。这是lambda表达式。@dbnex14请查看lambda表达式的问题:我添加了更新。它在那条线上出错了。Thanks@dbnex14您正在定义字符串数组,而它应该是Car;)var cars=新车[]{new Car{Model=“Mazda”},新车{Model=“VW”},新车{Model=“Audi”},新车{Model=“BMW”},新车{Model=“Honda”};你在哪里设定汽车的价值观“马自达”、“大众”、“奥迪”?谢谢,我正在使用我的模型在表单上设置一些默认值。对不起,我是WPF的新手,只是想澄清为什么我需要这个。因此,当窗体打开时,默认情况下,这些值应该显示在我的控件中(在本例中是Car组合框,但我发布了带有两个其他控件的更新)。从新的更新中确定,Make和Year属性应该位于Car类中,而不是ViewModel中。DefaultCar应该分配给car的一个实例,而不是一个字符串,然后将其从ViewModel构造函数中删除。@E-Bat您是说ViewModel类应该只包含IEnumerable Cars,而其他所有内容都应该移动到car类吗?或者我应该从ViewModel C-TOR中删除它?在这种情况下,如何将DefaultCar分配给car的实例?它不是已经用上面的表达式赋值了吗?是否可以显示更改?dbnex14,在这种情况下,ViewModel应仅包含Cars和DefaultCar属性。DefaultCar可以在您从数据存储中获取车辆的瞬间分配。当您的视图加载并尝试解析其绑定时,将从您的视图中查询它们的Cars属性(由ComboBox中的ItemsSource属性触发)。此时,您可以在返回列表之前分配DefaultCar。请参阅下面的答案。顺便说一句,它应该是SelectedCar而不是DefaultCar,因为它是如何在SelectedItem绑定中定义的ComboBox@E-但我认为我的问题有误导性。因此,我将此标记为已回答,并创建了一个新的,以更好地解释我想要实现的目标。
<ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}"
UpdateSourceTrigger=PropertyChanged}"/>