WPF绑定ComboBox到我的ViewModel

时间:2015-12-16 20:04:26

标签: c# wpf xaml mvvm

我正在尝试将我的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。我想在我的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>

我有两个问题:

  1. 如何将组合框中选择的默认值设置为“VW”(一旦表单加载,它应该在组合框中显示“VW”)。
  2. 如何在xaml中设置如上所述的ComboBoxItems,如何在我的ViewModel中设置它然后在ComboBox中加载它们?
  3. 谢谢,

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

2 个答案:

答案 0 :(得分:8)

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

你的Xaml:

<ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}" 
        UpdateSourceTrigger=PropertyChanged}"/>

答案 1 :(得分:5)

  1. 默认值: 如果设置viewModel.Car = "VW",则应在组合框中自动选择该项。 为此,您需要在设置INotifyPropertyChanged之前实施Car或设置DataContext
  2. 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。