WPF将组合框绑定到我的ViewModel

本文关键字:我的 ViewModel 绑定 组合 WPF | 更新日期: 2023-09-27 18:27:08

我正在尝试将ViewModel绑定到ComboBox。我有这样定义的ViewModel类:

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中,我这样做是为了将ComboBox绑定到此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>

我有两个问题:

  1. 如何将组合框中选择的默认值设置为"VW"(一旦加载表单,它应该在组合框中显示"VW")
  2. 与其在xaml中设置如上所述的ComboBoxItems,我如何在ViewModel中设置它,然后在ComboBox中加载这些

谢谢,

更新:到目前为止,我设法实现了这一点,但在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; }
    }
}

WPF将组合框绑定到我的ViewModel

当你要实现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; }
    }

您的Xaml:

<ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}" 
        UpdateSourceTrigger=PropertyChanged}"/>
  1. 默认值:如果您设置了viewModel.Car = "VW",那么它应该在组合框中自动选择该项目。为此,您需要在设置DataContext之前实现INotifyPropertyChanged或设置Car

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。绑定ItemsSourceSelectedItem

<ComboBox ItemsSource="{Binding Cars}"
          SelectedItem="{Binding Car, Mode=TwoWay}">
</ComboBox>

如果源代码或视图比只显示字符串更复杂,也可以设置ComboBox.ItemTemplate

    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>

在视图模型中只需添加一个列表属性:

public ObservableCollection<string> Cars { get; set; }

它不一定是ObservableCollection,但只要您更改集合,该类型就会自动更新UI。