2015-12-16 12 views
5

Tôi đang cố gắng ràng buộc ViewModel của tôi vào ComboBox của tôi. Tôi có lớp ViewModel được định nghĩa như thế này:WPF Binding ComboBox vào ViewModel

class ViewModel 
{ 
    public ViewModel() 
    { 
     this.Car= "VW"; 
    } 

    public string Car{ get; set; } 
} 

tôi đặt ViewModel này như DataContext trong Window_Load như:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     this.DataContext = new CarModel(); 
    } 

Sau đó, trong XAML của tôi, tôi làm điều này để ràng buộc ComboBox của tôi để ViewModel này. Tôi muốn hiển thị "VW" như chọn theo mặc định trong ComboBox của tôi:

 <ComboBox Name="cbCar" SelectedItem="{Binding Car, UpdateSourceTrigger=PropertyChanged}"> 
      <ComboBoxItem Tag="Mazda">Mazda</ComboBoxItem> 
      <ComboBoxItem Tag="VW">VW</ComboBoxItem> 
      <ComboBoxItem Tag="Audi">Audi</ComboBoxItem> 
     </ComboBox> 

Tôi có 2 câu hỏi:

  1. Làm thế nào để thiết lập giá trị mặc định được chọn trong Combo Box để "VW" (một lần tải biểu mẫu, nó sẽ hiển thị "VW" trong hộp tổ hợp).
  2. Thay vì thiết lập ComboBoxItems như trên trong xaml, làm thế nào để tôi đặt nó trong ViewModel của tôi và sau đó tải chúng trong ComboBox?

Cảm ơn,

UPDATE: Cho đến nay, tôi quản lý để thực hiện điều này nhưng tôi nhận được lỗi như sau trong 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; } 
    } 
} 
+0

Ok từ của bạn các thuộc tính cập nhật, Tạo và Năm mới phải nằm trong lớp Ô tô chứ không phải trong ViewModel. DefaultCar nên được gán cho một thể hiện của ô tô, không phải một chuỗi và loại bỏ nó khỏi hàm tạo ViewModel của bạn. –

+0

@ E-Bat Bạn có nói rằng ViewModel CLASS chỉ nên giữ IEnumerable Ô tô và mọi thứ khác nên được chuyển sang Car CLASS? Hoặc tôi chỉ cần loại bỏ nó từ ViewModel C-TOR? Và làm thế nào để gán DefaultCar cho ví dụ của một chiếc xe trong trường hợp này? Không phải nó đã được gán bằng cách sử dụng biểu thức trên? Có thể cho thấy sự thay đổi không? – pixel

+1

dbnex14, Trong trường hợp này, ViewModel chỉ nên chứa Ô tô và các thuộc tính DefaultCar. DefaultCar có thể được chỉ định trong thời điểm bạn nhận được Ô tô từ kho dữ liệu của bạn. Khi View của bạn tải và nó cố gắng để giải quyết các ràng buộc của nó, họ tài sản Ô tô sẽ được truy vấn từ View của bạn (kích hoạt bởi ItemsSource bất động sản từ ComboBox). Sau đó, trong thời điểm này, bạn có thể gán DefaultCar trước khi trả về danh sách. Xem câu trả lời của tôi dưới đây. –

Trả lời

7

Như bạn goint để thực hiện MVVM nó sẽ tốt hơn rất nhiều nếu bạn bắt đầu suy nghĩ trong đối tượng để đại diện cho Ô tô trong ứng dụng của bạn:

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 của bạn:

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

Cảm ơn. làm thế nào bạn sẽ viết lại dòng này, tôi không hiểu những gì nó làm như "xe" là hư không được xác định "SelectedCar = cars.FirstOrDefault (car => car.Model ==" VW ");"? Thansk, – pixel

+1

@ dbnex14, biến số xe đại diện cho từng mục trong bộ sưu tập xe ô tô, nó không cần phải được xác định trước đó. Nhìn vào xe cú pháp =>. Đây là biểu thức lambda. –

+1

@ dbnex14 hãy xem câu hỏi này cho các biểu thức lambda: http://stackoverflow.com/questions/3970219/c-sharp-lambda –

3
  1. Giá trị mặc định: Nếu bạn thiết lập viewModel.Car = "VW", sau đó nó sẽ tự động chọn mục đó trong hộp kết hợp. Để làm việc này, bạn cần phải triển khai INotifyPropertyChanged hoặc đặt Car trước khi bạn đặt DataContext.

thực hiện INotifyPropertyChanged có thể trông giống như:

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 ItemsSourceSelectedItem.

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

Bạn cũng có thể thiết lập ComboBox.ItemTemplate nếu nguồn hoặc xem của bạn là phức tạp hơn là chỉ hiển thị một chuỗi:

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

Trong mô hình quan điểm chỉ cần thêm một tài sản danh sách:

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

Nó không phải là ObservableCollection nhưng loại đó sẽ tự động cập nhật giao diện người dùng bất cứ khi nào bạn thay đổi bộ sưu tập.

+0

Nơi nào bạn đặt Ô tô thành giá trị "Mazda", "VW", "Audi"? Cảm ơn – pixel

+1

@ dbnex14 đã cập nhật câu trả lời để khởi tạo Ô tô – FUR10N

+0

Tôi đang sử dụng mô hình của mình để đặt một số giá trị mặc định trên biểu mẫu. Xin lỗi, tôi mới tham gia WPF, chỉ muốn làm rõ lý do tại sao tôi cần điều này. Vì vậy, khi các biểu mẫu mở, các giá trị này sẽ được hiển thị theo mặc định trong các điều khiển của tôi (trong ví dụ này là hộp kết hợp Ô tô nhưng tôi đã đăng cập nhật bằng một vài điều khiển khác). – pixel