我可以连接两个没有DependencyProperty的ViewModel吗?

时间:2019-07-11 00:48:00

标签: wpf mvvm parent-child viewmodel

我有MainWindow(为简化起见,已简化):

<Window>
    <!-- (...) -->

    <Window.DataContext>
         <vm:MainWindowViewModel />
    </Window.DataContext>

    <!-- (...) -->

    <CheckBox IsChecked="{Binding ShowAdvanced}" Content="Advanced view" />
    <uc:MyUserControl DataContext={Binding MyUserControlViewModel} />
</Window>

MainWindowViewModel:

public partial class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
         MyUserControlVM = new MyUserControlViewModel();
    }

    private bool _showAdvanced;
    public bool ShowAdvanced
    {
        get => _showAdvanced;
        set { _showAdvanced = value; NotifyPropertyChanged(); }
    }

    private MyUserControlViewModel _myUserControlVM;
    public MyUserControlViewModel MyUserControlVM
    {
        get => _myUserControlVM;
        set { _myUserControlVM= value; NotifyPropertyChanged(); }
    }
}

在我的UserControl中,当未选中“显示高级”复选框时,我应该隐藏了一些控件。

<GroupBox Header="Some advanced stuff"
    Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.(vm:MainWindowViewModel.ShowAdvanced), Converter={StaticResource BoolToVis}}">
    <!-- (...) -->
</GroupBox>

这实际上有效,但是我不喜欢这样,因为UserControl依赖MainWindow。

如何在没有DependencyProperty的情况下正确连接这些视图模型?

我尝试将其添加到MyUserControlViewModel:

public MyUserControlViewModel(MainWindowViewModel parent)
{
    Parent = parent;
}

private MainWindowViewModel _parent;
public MainWindowViewModel Parent
{
    get { return _parent; }
    set { _parent = value; NotifyPropertyChanged(); }
}

并在这样的MyUserControl控件之一上绑定可见性:

Visibility="{Binding Parent.ShowAdvanced}"

但是这不起作用(没有通知MyUserControl?)。

1 个答案:

答案 0 :(得分:0)

每当将新值分配给ShowAdvanced MainViewModel属性时,将ShowAdvanced属性添加到控制VM并将值分配给每个控制VM。

public class MainViewModel : Base.ViewModelBase
{
    private bool _showAdvanced;

    public MainViewModel()
    {
        MyUserControl1 = new MyUserControlViewModel { Message = "Control 1" };
        MyUserControl2 = new MyUserControlViewModel { Message = "Control 2" };
        MyUserControl3 = new MyUserControlViewModel { Message = "Control 3" };
    }

    public bool ShowAdvanced
    {
        get => _showAdvanced;
        set
        {
            this.RaiseAndSetIfChanged( ref _showAdvanced, value );
            MyUserControl1.ShowAdvanced = value;
            MyUserControl2.ShowAdvanced = value;
            MyUserControl3.ShowAdvanced = value;
        }
    }

    public MyUserControlViewModel MyUserControl1 { get; }
    public MyUserControlViewModel MyUserControl2 { get; }
    public MyUserControlViewModel MyUserControl3 { get; }
}

public class MyUserControlViewModel : Base.ViewModelBase
{
    private bool _showAdvanced;
    private string _message;

    public bool ShowAdvanced { get => _showAdvanced; set => this.RaiseAndSetIfChanged( ref _showAdvanced, value ); }
    public string Message { get => _message; set => this.RaiseAndSetIfChanged( ref _message, value ); }
}