首页 > 解决方案 > 将按钮绑定到不同的 ViewModel [MVVM]

问题描述

我在一个View中有两个按钮,是否可以将一个按钮绑定到第一个ViewModel中的一个命令,另一个按钮绑定到第二个ViewModel中的第二个命令?只需添加两个ViewModel都已初始化。

    <Button Command="{Binding ElementName=MainTreeView, Path=DataContext.FirstCommand}" CommandParameter="{Binding NameE}">
    <Label Content="{Binding NameE}"/>
 </Button>
  <Button Command="{Binding ElementName=MainTreeView, Path=DataContext.SecondCommand}" CommandParameter="{Binding NameD}">
    <Label Content="{Binding NameD}"/>
 </Button>

还有我的两个ViewModel

public class FirstViewModel : INotifyPropertyChanged
{
     public MyICommand<string> FirstCommand { get; private set; }

     public HomeViewModel()
    {
        FirstCommand = new MyICommand<string>(myFirstCommand);
    }

    public void myFirstCommand(string par)
    {
        Console.Beep();
    }
}


public class SecondViewModel : INotifyPropertyChanged
{
     public MyICommand<string> SecondCommand { get; private set; }

     public HomeViewModel()
    {
        SecondCommand = new MyICommand<string>(mySecondCommand);
    }

    public void mySecondCommand(string par)
    {
        Console.Beep();
    }
}

编辑:在我有按钮的视图中<ContentPresenter Content="{Binding Content}"/>,内容有View和我想用按钮到达的ViewModel

标签: c#.netwpfmvvm

解决方案


最简单和最通用的解决方案是通过在 App.xaml 中实例化您的视图模型来全局访问它们ResourceDictionary

应用程序.xaml:

<Application ...>
  <Application.Resources>
    <ResourceDictionary>
      <FirstViewModel x:Key="FirstViewModel" />
      <SecondViewModel x:Key="SecondViewModel" />
    </ResourceDictionary>
  </Application.Resources>
</Application>

或使用 C#(例如,App.xaml.cs)

Application.Current.Resources.Add("FirstViewModel", new FirstViewModel(arg1, arg2));
Application.Current.Resources.Add("SecondViewModel", new SecondViewModel(arg1, arg2));

现在您可以从任何视图引用它们:

<Button Content="{Binding NameE}" 
        CommandParameter="{Binding NameE}" 
        Command="{Binding Source={StaticResource FirstViewModel}, Path=FirstCommand}" />

<Button Content="{Binding NameD}" 
        CommandParameter="{Binding NameD}" 
        Command="{Binding Source={StaticResource SecondViewModel}, Path=SecondCommand}" />

另一种解决方案是使用组合并将视图模型包装到父视图模型中:

public class MainViewModel : INotifyPropertyChanged
{
  public FirstViewModel FirstViewModel { get; private set; }
  public SecondViewModel SecondViewModel { get; private set; }

  public MainViewModel()
  {
    this.FirstViewModel = new FirstViewModel();
    this.SecondViewModel = new SecondViewModel();
  }
}

public class FirstViewModel : INotifyPropertyChanged
{
  public MyICommand<string> FirstCommand { get; private set; }

  public FirstViewModel()
  {
    FirstCommand = new MyICommand<string>(myFirstCommand);
  }

  public void myFirstCommand(string par)
  {
    Console.Beep();
  }
}


public class SecondViewModel : INotifyPropertyChanged
{
  public MyICommand<string> SecondCommand { get; private set; }

  public SecondViewModel()
  {
    SecondCommand = new MyICommand<string>(mySecondCommand);
  }

  public void mySecondCommand(string par)
  {
    Console.Beep();
  }
}

用法

<TreeView x:Name="MainTreeView">
  <TreeView.DataContext>
    <MainViewModel />
  </TreeView.DataContext>
</TreeView>


<Button Content="{Binding NameE}" 
        CommandParameter="{Binding NameE}" 
        Command="{Binding ElementName=MainTreeView, Path=DataContext.FirstViewModel.FirstCommand}" />

<Button Content="{Binding NameD}" 
        CommandParameter="{Binding NameD}" 
        Command="{Binding ElementName=MainTreeView, Path=DataContext.SecondViewModel.SecondCommand}" />

推荐阅读