为多个WPF页面创建单个控制器

本文关键字:创建 单个 控制器 WPF | 更新日期: 2023-09-27 18:15:27

我是WPF的新手,也是c# . net的初学者。我目前正在制作一个应用程序,其中将有许多页面,而改变页面的触发器是使用Kinect SDK的手势(触发方法与此问题无关)。通常在创建WPF文件时,会附加一个类似的.cs文件,它的作用有点像控制器。但是,我需要多个WPF文件/页面仅由单个控制器.cs文件控制。我该怎么做呢?谢谢你看我的问题,你的回答将是非常感谢:)

为多个WPF页面创建单个控制器

你可能想写一个包含你的'控制器'代码的类,并从你的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}}"/>