其他视图中的视图(WPF/MVVM)



我有一个UserControl叫做ControlButtonsView

<Grid>
<Button Style="{StaticResource MinimizeButton}" Command="{Binding MinimizeAppCommand}" Height="40" Width="120" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Button Content="X" Style="{StaticResource ExitButton}" Command="{Binding ExitAppCommand}" Height="40" Width="60" VerticalAlignment="Top" HorizontalAlignment="Right"/>
</Grid>

和ControlButtonsViewModel

class ControlButtonsViewModel
{
private MainWindow _mainWindow;
public ICommand MinimizeAppCommand { get; set; }
public ICommand ExitAppCommand { get; set; }
public ControlButtonsViewModel(MainWindow mainWindow)
{
_mainWindow = mainWindow;
MinimizeAppCommand = new BaseICommand(MinimizeApp);
ExitAppCommand = new BaseICommand(ExitApp);
}
public void MinimizeApp(object obj)
{
_mainWindow.WindowState = System.Windows.WindowState.Minimized;
}
public void ExitApp(object obj)
{
_mainWindow.Close();
}
}

在我的mainwindow . example .cs

this.DataContext = new AppManagerViewModel();

AppManagerViewModel控制视图之间的切换

我想要的是能够使用这个ControlButtonsView与它的ControlButtonsViewModel在多个其他视图,这个视图是一个UserControl与最小化和最大化按钮,我想在多个视图中使用它们,在LogInView, MenuView等。

如果有更简单的方法,请告诉我)谢谢。

Window逻辑不属于视图模型。视图模型不关心UI。你必须总是实现视图模型,假装没有UI,只有一个模型。

因此,在视图模型中引用MainWindow将导致应用程序与视图/UI的紧密耦合。

MVVM的目标是消除这种紧密耦合。显然,由于您引入的紧密耦合,您目前没有实现MVVM模式(您实现的方式是错误的)。
例如,如果不创建视图,您将无法测试视图模型。

将视图作为构造函数依赖项注入会使情况更糟。

因为这些命令执行UI逻辑(关闭,最小化),所以它们必须从MVVM的角度移动到控件-视图组件。

为了使这些命令在整个视图中可用,或者相对于实际的可视化树全局可用,你应该将这些命令实现为路由命令,例如在你的MainWindow上,你想通过命令来控制。

由于路由命令是静态的,它们可以被任何其他控件引用。因为它们是路由的,所以它们可以在命令目标(MainWindow)所属的同一可视树中的任何地方使用。

内部命令,一旦执行,将引发一个路由事件,该事件将遍历可视化树,直到找到一个处理程序。

命令概述

在您的情况下,MainWindow将注册Execute和CanExecute处理程序来关闭或最小化本身

下面的示例只实现了关闭Window的逻辑。
您可以遵循模式来提供额外的逻辑,例如最大化Window:

MainWindow.xaml.cs

partial class MainWindow : Window
{
public static readonly RoutedUICommand CloseWindowRoutedCommand = new RoutedUICommand(
"Closes the application.", 
nameof(MainWindow.CloseWindowRoutedCommand), 
typeof(MainWindow));

public MainWindow()
{
InitializeComponent();
this.CommandBindings.Add(
new CommandBinding(MainWindow.CloseWindowRoutedCommand, 
ExecuteCloseWindow, 
CanExecuteCloseWindow));
}
private void CanExecuteCloseWindow(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = true;
private void ExecuteCloseWindow(object sender, ExecutedRoutedEventArgs e) => Close();
}

ControlButtonsView.xaml

<Grid>
<-- ICommand traverse visual tree until handler(s) is found -->
<Button Content="X" Command="{x:static MainWindow.CloseWindowRoutedCommand}" />
</Grid>
  1. AppManagerViewModel中添加ControlButtonsViewModel的属性

    public ControlButtonsViewModel ControlButtonsViewModel {get; set;}

  2. AppManagerViewModel的构造函数中添加ControlButtonsViewModel = new ControlButtonsViewModel();

  3. In Xaml ofAppManagerView

    ControlButtonsView DataContext="{Binding ControlButtonsViewModel}"…/在

相关内容

  • 没有找到相关文章

最新更新