C# 视图到视图模型到设置

C# 视图到视图模型到设置,c#,wpf,xaml,mvvm,application-settings,C#,Wpf,Xaml,Mvvm,Application Settings,是否可以将currentDevices重构为一个集合? 基本上,我有三个组合框,其中selectedvalue绑定到currentDevices。然后从设置文件中获取当前设备 看法 我将编写一个设备选项viewmodel,并为主viewmodel提供一个可观的集合 DeviceOptionViewModel.cs public class DeviceOptionViewModel : INotifyPropertyChanged { public event PropertyChan

是否可以将currentDevices重构为一个集合? 基本上,我有三个组合框,其中selectedvalue绑定到currentDevices。然后从设置文件中获取当前设备

看法


我将编写一个
设备选项viewmodel
,并为主viewmodel提供一个可观的集合

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; }
}
主要虚拟机:

    public ObservableCollection<DeviceOptionViewModel> 
        CurrentDevices { get; private set; }
            = new ObservableCollection<DeviceOptionViewModel>();
公共可观测集合
CurrentDevices{get;private set;}
=新的ObservableCollection();
XAML:


返回主视图模型:

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
    }
}
受保护的void PopulateCurrentDevices(IEnumerable strings fromwhere)
{
CurrentDevices.Clear();
foreach(StringsFromwhere中的var设备)
{
var dovm=新设备选项ViewModel(){
当前设备=设备,
AvailableDevices=this.AvailableDevices
};
dovm.PropertyChanged+=设备选项视图模型\u PropertyChangedHandler;
CurrentDevices.Add(dovm);
}
}
受保护的无效设备选项ViewModel\u属性更改句柄(对象发送器,
PropertyChangedEventArgs(e)
{
var dopt=发送方作为设备选项ViewModel;
if(e.PropertyName==nameof(DeviceOptionViewModel.CurrentDevice))
{
//做事
}
}
因此,您可以根据需要在viewmodel中填充和重新填充
CurrentDevices
,如果所有通知都正确完成,UI将神奇地出现


如果创建一个新的
ObservableCollection
并将其分配给
CurrentDevices
属性,则需要在主视图模型上提升
PropertyChanged(nameof(CurrentDevices))
。我将setter设置为私有,以避免实现该细节。如果它不是一个庞大的集合,也可以在同一个旧实例上执行
Clear()
Add()

总是有三种设备吗?可能不值得。除了没有用骆驼套外,名字也很可怕。我就坐在这里,假设你为了问这个问题而重命名了它们。不,设备的数量是可变的。为了简单起见,我还重新命名了它们。那么Ed下面的回答就是一个很好的方法!
    public ObservableCollection<DeviceOptionViewModel> 
        CurrentDevices { get; private set; }
            = new ObservableCollection<DeviceOptionViewModel>();
<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>
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
    }
}