2016-04-22 5 views
1

currentDevicesをコレクションにリファクタリングすることは可能ですか? 基本的には、selectedValueがcurrentDevicesにバインドされている3つのコンボボックスがあります。 currentDevicesは設定ファイルから取得されます。View to Model to Settings

ビュー

<ComboBox ItemsSource="{Binding availableDevices}" 
      SelectedValue="{Binding currentDevice1}"> 
</ComboBox> 
<ComboBox ItemsSource="{Binding availableDevices}" 
      SelectedValue="{Binding currentDevice2}"> 
</ComboBox> 
<ComboBox ItemsSource="{Binding availableDevices}" 
      SelectedValue="{Binding currentDevice3}"> 
</ComboBox> 

のViewModel

public string currentDevice1 { 
    get 
    { 
     return SampleSettings.Default.Device1; 
    } 
    set 
    { 
     SampleSettings.Default.Device1 = value; 
    } 

} 
public string currentDevice2 
{ 
    get 
    { 
     return SampleSettings.Default.Device2; 
    } 
    set 
    { 
     SampleSettings.Default.Device2 = value; 
    } 
} 
public string currentDevice3 
{ 
    get 
    { 
     return SampleSettings.Default.Device3; 
    } 
    set 
    { 
     SampleSettings.Default.Device3 = value; 
    } 
} 
+0

常に3つのデバイスがありますか?おそらくその価値はありません。キャメルではないことを除けば、その名前はひどいものです。私はあなたがこの質問をするために名前を変更したと仮定して、ここに座ります。 – Will

+0

いいえ、可変数のデバイスが存在します。私も簡単にするために名前を変更しました。 –

+0

次にEdの答えはこれを行う良い方法です。 – Will

答えて

2

私はDeviceOptionViewModelを書き、そしてメインのviewmodelにのObservableCollectionを与えると思います。

DeviceOptionViewModel.cs

public class DeviceOptionViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string _currentDevice; 
    public String CurrentDevice { 
     get { return _currentDevice; } 
     set { 
      _currentDevice = value; 
      PropertyChanged?.Invoke(this, 
       new PropertyChangedEventArgs(nameof(CurrentDevice)); 
     } 
    } 

    // Parent event assigns this to his own availableDevices 
    // when he creates this. 
    public IEnumerable AvailableDevices { get; set; } 
} 

メインVM:

public ObservableCollection<DeviceOptionViewModel> 
     CurrentDevices { get; private set; } 
      = new ObservableCollection<DeviceOptionViewModel>(); 

XAML:

<ItemsControl 
    ItemsSource="{Binding CurrentDevices}" 
    > 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <!-- DataContext here is DeviceOptionViewModel. We gave it its 
       own reference to AvailableDevices to simplify binding. --> 
      <ComboBox 
       ItemsSource="{Binding AvailableDevices}" 
       SelectedValue="{Binding CurrentDevice}" 
       /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

戻るメインのviewmodelへ:

protected void PopulateCurrentDevices(IEnumerable<String> stringsFromWherever) 
{ 
    CurrentDevices.Clear(); 

    foreach (var device in stringsFromWherever) 
    { 
     var dovm = new DeviceOptionViewModel() { 
       CurrentDevice = device, 
       AvailableDevices = this.availableDevices 
      }; 

     dovm.PropertyChanged += DeviceOptionViewModel_PropertyChangedHandler; 

     CurrentDevices.Add(dovm); 
    } 
} 

protected void DeviceOptionViewModel_PropertyChangedHandler(object sender, 
    PropertyChangedEventArgs e) 
{ 
    var dopt = sender as DeviceOptionViewModel; 

    if (e.PropertyName == nameof(DeviceOptionViewModel.CurrentDevice)) 
    { 
     // Do stuff 
    } 
} 

したがって、必要に応じてCurrentDevicesをあなたのviewmodelに移入して再投入すれば、すべての通知が正しく行われるとUIが魔法のように表示されます。

新しいObservableCollectionを作成し、それをCurrentDevicesプロパティに割り当てる場合は、メインのビューモデルで​​を上げる必要があります。その詳細を実装する必要がないように、私はセッターをプライベートにしました。それが巨大なコレクションでない場合は、同じ古いインスタンス上にClear()Add()だけがあるかもしれません。

+0

ちょうどそれが働いた!どうもありがとうございました! –

+0

@PaoloGo私の喜び! –