为多个WPF页面创建单个控制器
本文关键字:创建 单个 控制器 WPF | 更新日期: 2023-09-27 18:15:27
我是WPF的新手,也是c# . net的初学者。我目前正在制作一个应用程序,其中将有许多页面,而改变页面的触发器是使用Kinect SDK的手势(触发方法与此问题无关)。通常在创建WPF文件时,会附加一个类似的.cs文件,它的作用有点像控制器。但是,我需要多个WPF文件/页面仅由单个控制器.cs文件控制。我该怎么做呢?谢谢你看我的问题,你的回答将是非常感谢:)
你可能想写一个包含你的'控制器'代码的类,并从你的WPF UserControls/Pages中引用它。
新建文件:
public class MyController
{
public void DoThings(object parameter)
{
// stuff you want to do
}
}
,然后在你的UserControl代码隐藏类中:
public partial class MyWpfControl : UserControl
{
private MyController controller;
public MyWpfControl
{
this.controller = new MyController();
}
}
最后,将事件绑定到控制器的方法:
private void OnGesture(object sender, EventArgs e)
{
// call the method on the controller, and pass whatever parameters you need...
this.controller.DoThings(e);
}
后面的代码实际上是视图的一部分,并不真正类似于控制器,通常它们中不应该有太多代码。通常情况下,你会希望你的大部分逻辑之间的"视图模型",作为一个抽象的视图和"模型",作为一个抽象的业务逻辑,你的UI交互。
从这个角度来看,我认为你真正想要的是一个控制多个视图的视图模型(VM)。这是一个相当典型的场景,首选的方法(无论如何)是有一个分层视图模型,它有一个顶层的应用程序模型和一些子虚拟机,代表不同的组件在你的UI,虽然你可以绑定所有的东西到你的顶层虚拟机,如果你真的想。
要做到这一点,我们首先定义我们的视图模型如下
public interface IGestureSink
{
void DoGesture();
}
public class MyControlVM : INotifyPropertyChanged, IGestureSink
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private ApplicationVM parent;
public MyControlVM(ApplicationVM parent)
{
this.Name = "my user control";
this.parent = parent;
parent.PropertyChanged += (s, o) => PropertyChanged(this, new PropertyChangedEventArgs("Visible"));
}
public String Name { get; set; }
public bool Visible { get { return parent.ControlVisible; } }
public void DoGesture()
{
parent.DoGesture();
}
}
public class ApplicationVM : INotifyPropertyChanged, IGestureSink
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public ApplicationVM()
{
this.ControlVM = new MyControlVM(this);
this.ControlVisible = false;
}
public MyControlVM ControlVM { get; private set; }
public bool ControlVisible {get; set;}
public void DoGesture()
{
this.ControlVisible = !this.ControlVisible;
PropertyChanged(this, new PropertyChangedEventArgs("ControlVisible"));
}
}
然后我们需要做的就是创建一个用户控件
<UserControl x:Class="WpfApplication2.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Background="LightBlue">
<Label Content="{Binding Name}"/>
</Grid>
</UserControl>
页面和
<Window xmlns:my="clr-namespace:WpfApplication2" x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<my:MyControl Width="200" Height="200" x:Name="myUserControl" DataContext="{Binding ControlVM}" Visibility="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="222,262,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
使用它。在后面的代码中,我们唯一需要的是一个构造函数,用于设置页面VM并将按钮连接到视图模型。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ApplicationVM();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
((IGestureSink)(this.DataContext)).DoGesture();
}
}
如果你想使用一个整体视图模型,你可以使用这个,而不是将DataContext绑定到ControlVM
:
<my:MyControl Width="200" Height="200" x:Name="myUserControl" DataContext="{Binding DataContext}" Visibility="{Binding ControlVisible,Converter={StaticResource BooleanToVisibilityConverter}}"/>