2015-12-16 33 views
5

ViewModel'imi ComboBox'ımla bağlamaya çalışıyorum.WPF Bağlama ComboBox ViewModel'e

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

    public string Car{ get; set; } 
} 

ben gibi Window_Load içinde DataContext olarak bu ViewModel ayarlayın:: Benim xaml Sonra

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

, bu ViewModel benim ComboBox bağlamak için bunu böyle tanımlanan ViewModel sınıf var. benim ComboBox varsayılan olarak seçilmiş gibi "VW" göstermek istiyorum: Ben varsayılan değer açılan kutu için "VW" (bir kez seçilen seti nasıl

  1. :

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

    ben 2 soru var form yükler, açılan kutuda "VW" göstermelidir).

  2. Yukarıdaki gibi ComboBoxItems'i xaml olarak ayarlamak yerine, onu ViewModel'de nasıl ayarlayabilirim ve sonra bunları ComboBox'ta yüklerim?

sayesinde

GÜNCELLEME: Şimdiye kadar, bu uygulamaya yönetmek ama ViewModel c-tor aşağıdaki gibi hata alıyorum:

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

Tamam Yeni güncelleme, Marka ve Yıl özellikleri, ViewModel'de değil, Araba sınıfında kullanılmalıdır. DefaultCar bir dizeye değil, bir arabelleğe atanmalı ve ViewModel yapıcınızdan kaldırılmalıdır. –

+0

@ E-Bat ViewModel CLASS'ın sadece IEnumerable Otomobilleri tutması gerektiğini ve bunun dışındaki her şeyin Car CLASS'a taşınması gerektiğini mi söylüyorsunuz? Ya da sadece ViewModel C-TOR'dan çıkarmalıyım? Ve bu durumda bir aracın örneğine DefaultCar nasıl atanır? Yukarıdaki ifadeyi kullanarak atanmamış mı? Değişikliği göstermek mümkün mü lütfen? – pixel

+1

dbnex14, Bu durumda ViewModel sadece Otomobil ve DefaultCar özelliklerini içermelidir. Otomobilleri veri mağazanızdan aldığınız anda DefaultCar atanabilir. Görünümünüz yüklendiğinde ve bağlantılarını çözmeyi denediğinde, Cars özelliği Görünümünüzden sorgulanır (ComboBox'tan ItemsSource özelliği tarafından tetiklenir). Sonra bu anda listeyi döndürmeden önce DefaultCar'ı atayabilirsiniz. Cevabımı görün feryat. –

cevap

7

Eğer uygulamanızda Cars temsil etmek nesneleri düşünmeye başlarsanız çok daha iyi olacak MVVM uygulamak goint olduğundan:

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; } 
    } 

Sizin Xaml: hesabınızla ilgili

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

Teşekkürler. bu çizgiyi nasıl yeniden yazarsın, "araba" nın hiçbir yerde tanımlanmadığını anlamadım "SelectedCar = cars.FirstOrDefault (car => car.Model ==" VW ");"? Thansk, – pixel

+1

@ dbnex14, araba değişkeni araba koleksiyonundaki her bir öğeyi temsil eder, daha önce tanımlanmasına gerek yoktur. Sözdizimi arabasına bakın =>. Bu lambda ifadesidir. –

+1

@ dbnex14 lütfen lambda ifadeleri için şu soruya bakın: http://stackoverflow.com/questions/3970219/c-sharp-lambda –

3
  1. Standart Değeri: Eğer viewModel.Car = "VW"'u ayarladıktan sonra, açılan kutuda o öğeyi otomatik seçmelidir. Bunun çalışması için, DataContext'u ayarlamadan önce ya INotifyPropertyChanged uygulamalısınız veya Car ayarlanmalıdır.

INotifyPropertyChanged uygulama görünebilir gibi:

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 ItemsSource ve SelectedItem.

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

: Sadece bir liste özelliği eklemek görünümü modelinde

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

:

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

Ayrıca kaynak veya görünüm sadece bir dize görüntüleyen daha karmaşık ise ComboBox.ItemTemplate ayarlayabilirsiniz ObservableCollection olmak zorunda değildir, ancak bu tür koleksiyonu değiştirdiğinizde kullanıcı arayüzünü otomatik olarak günceller.

+0

Otomobilleri "Mazda", "VW", "Audi" değerlerine nereye koyarsınız? Teşekkürler – pixel

+1

@ dbnex14 otomobil – FUR10N

+0

başlatmak için cevabı güncellendi formda bazı varsayılan değerler ayarlamak için benim model kullanıyorum. Maalesef, WPF'ye yeni geldim, neden buna ihtiyacım olduğunu açıklığa kavuşturmak istiyorum. Bu yüzden, formlar açıldığında, bu değerler benim denetimlerimde varsayılan olarak gösterilmeli (bu örnekte, Araç açılan kutucuğu ancak birkaç başka denetim ile güncelleştirme gönderdim). – pixel