WPF 将 ComboBox 绑定到我的 ViewModel
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34321074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Binding ComboBox to my ViewModel
提问by pixel
I am trying to bind my ViewModel to my ComboBox. I have ViewModel class defined like this:
我正在尝试将我的 ViewModel 绑定到我的 ComboBox。我有这样定义的 ViewModel 类:
class ViewModel
{
public ViewModel()
{
this.Car= "VW";
}
public string Car{ get; set; }
}
I set this ViewModel as DataContext in Window_Load like:
我在 Window_Load 中将此 ViewModel 设置为 DataContext ,例如:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new CarModel();
}
Then in my xaml, I do this to bind my ComboBox to this ViewModel. I want to show the "VW" as selected by default in my ComboBox:
然后在我的 xaml 中,我这样做是为了将我的 ComboBox 绑定到这个 ViewModel。我想在我的 ComboBox 中显示默认选择的“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>
I have 2 questions:
我有两个问题:
- How do I set default value selected in Combo Box to "VW" (once form loads, it should show "VW" in combo box).
- Instead of setting ComboBoxItems like above in xaml, how to I set it in my ViewModel and then load these in ComboBox?
- 如何将组合框中选择的默认值设置为“VW”(一旦表单加载,它应该在组合框中显示“VW”)。
- 不是在 xaml 中像上面那样设置 ComboBoxItems,如何在我的 ViewModel 中设置它,然后在 ComboBox 中加载它们?
Thanks,
谢谢,
UPDATE: So far, I manage to implement this but I get error as below in the ViewModel c-tor:
更新:到目前为止,我设法实现了这一点,但在 ViewModel c-tor 中出现如下错误:
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; }
}
}
回答by E-Bat
As you are goint to implement MVVM it will be a lot better if you start to think in objects to represent Cars in your application:
当您将要实现 MVVM 时,如果您开始考虑在应用程序中使用对象来表示汽车,那将会好得多:
public class ViewModel
{
public Car SelectedCar{ get; set; }
public IEnumerable<Car> Cars{
get {
var cars = 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; }
}
Your Xaml:
你的 Xml:
<ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}"
UpdateSourceTrigger=PropertyChanged}"/>
回答by FUR10N
- Default Value:
If you set
viewModel.Car = "VW", then it should auto-select that item in the combo box. For this to work you will need to either implementINotifyPropertyChangedor setCarbefore you setDataContext.
- 默认值:如果您设置了
viewModel.Car = "VW",则它应该在组合框中自动选择该项目。为此,您需要在INotifyPropertyChanged设置Car之前实现或设置DataContext。
INotifyPropertyChanged implementation might look like:
INotifyPropertyChanged 实现可能如下所示:
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));
}
}
2.
Bind ItemsSourceand SelectedItem.
2. 绑定ItemsSource和SelectedItem。
<ComboBox ItemsSource="{Binding Cars}"
SelectedItem="{Binding Car, Mode=TwoWay}">
</ComboBox>
You can also set ComboBox.ItemTemplateif your source or view is more complex than just displaying a string:
您还可以设置ComboBox.ItemTemplate源或视图是否比仅显示字符串更复杂:
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
In the view model just add a list property:
在视图模型中只需添加一个列表属性:
public ObservableCollection<string> Cars { get; set; }
It doesn't have to be ObservableCollectionbut that type will auto-update the UI whenever you change the collection.
它不一定是,ObservableCollection但只要您更改集合,该类型就会自动更新 UI。

