gpt4 book ai didi

c# - MVVM - 如何从父 ViewModel 引用子 ViewModel(ViewModel 在其 View 中创建)?

转载 作者:行者123 更新时间:2023-12-03 10:12:58 26 4
gpt4 key购买 nike

如果我使用 Views 创建 ViewModel 实例且 ViewModel 没有对 View 的引用的方法,我不知道创建 viewmodel 关系的正确方法是什么。

假设我们有 ChildView 控件,它创建了一个具有 SaveCommand 的 ViewModel 实例。

<UserControl x:Class="App.ChildView" ...>
<UserControl.DataContext>
<local:ChildViewModel/>
</UserControl.DataContext>
<!-- some controls -->
</UserControl>

public class ChildViewModel
{
public RelayCommand SaveCommand { get; set; }
public ChildViewModel()
{
SaveCommand = new RelayCommand(SaveExecute);
}
private void SaveExecute()
{
Debug.WriteLine("Child data has been saved.");
}
}

现在,我将两个控件放在父 View 中,并希望对所有 subview 执行 SaveCommand。

<Window x:Class="App.ParentView" ...>
<Window.DataContext>
<local:ParentViewModel/>
</Window.DataContext>
<Grid>
<local:ChildView x:Name="child1"/>
<local:ChildView x:Name="child2"/>
<Button Content="Save All" Command="{Binding ParentSaveCommand}">
<Grid/>
</Window>

public class ParentViewModel
{
public RelayCommand ParentSaveCommand { get; set; }
public ParentViewModel()
{
ParentSaveCommand = new RelayCommand(ParentSaveExecute);
}
private void ParentSaveExecute()
{
Debug.WriteLine("Saving all has started...");

// <childVM1>.SaveCommand.Execute();
// <childVM2>.SaveCommand.Execute();

// From where should I get ChildViewModel?
}
}

我应该如何正确地引用 child 的 ViewModel?

我找到了可能的解决方案:
  • 向 ParentView 添加一个接口(interface),该接口(interface)返回 child 的 ViewModel ( like AngelSix did with the password )
  • 创建一个能够将 ChildView.DataContext 绑定(bind)到 ParentView.DataContext.Child1ViewModel 属性的类。

  • .

    或者也许这是错误的方法,ParentViewModel 应该创建一个 ChildViewModel 实例,而 ParentView 应该为 child1 和 child2 设置 DataContext(当然是通过绑定(bind))?

    最佳答案

    就像提到的 RTF 一样,对于这些类型的操作,让父虚拟机创建子虚拟机通常是一种更简单的方法,这样父虚拟机就可以维护对子虚拟机的引用。但是,您绝对可以在不改变架构的情况下做您想做的事。

    在 View 中:

     <Button
    Content="Save All"
    Height="37" Command="{Binding SaveAllCommand}">
    <Button.CommandParameter>
    <MultiBinding Converter="{StaticResource PassThroughConverter }">
    <Binding Path=“DataContext” ElementName="child1"/>
    <Binding Path=“DataContext” ElementName="child2"/>
    </MultiBinding>
    </Button.CommandParameter>
    </Button>

    转换器:
    public class PassThroughConverter : IMultiValueConverter
    {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
    return values.ToList();
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
    throw new NotSupportedException();
    }
    }

    在父 View 模型中:
    public class ParentViewModel
    {
    public RelayCommand<object> ParentSaveCommand { get; set; }
    public ParentViewModel()
    {
    this.ParentSaveCommand = new RelayCommand<object>(obj => this.ParentSaveExecute(obj));
    }
    private void ParentSaveExecute(object items)
    {
    foreach (var item in (ChildViewModel[])items)
    {
    item.SaveCommand.Execute();
    }
    }
    }

    关于c# - MVVM - 如何从父 ViewModel 引用子 ViewModel(ViewModel 在其 View 中创建)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58018846/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com