我有一个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>
-
在
AppManagerViewModel
中添加ControlButtonsViewModel
的属性public ControlButtonsViewModel ControlButtonsViewModel {get; set;}
-
在
AppManagerViewModel
的构造函数中添加ControlButtonsViewModel = new ControlButtonsViewModel();
-
In Xaml of
AppManagerView
,ControlButtonsView DataContext="{Binding ControlButtonsViewModel}"…/在