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

时间:2011-11-21 00:01:57

标签: c# wpf controller

我是WPF的新手,也是C#.NET的初学者。我目前正在创建一个应用程序,其中将有许多页面,并且更改页面的触发器是使用Kinect SDK的手势(触发方法与此问题无关)。通常,当创建WPF文件时,会附加一个类似名称的.cs文件,其行为有点像控制器。但是,我需要只有一个控制器.cs文件来控制多个WPF文件/页面。我如何实现这一目标?感谢您查看我的问题,我们非常感谢您的回答:)

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

背后的代码实际上是视图的一部分,并不是真正类似于控制器,通常不应该有太多的代码。通常,您希望在“视图模型”(用作视图的抽象)和“模型”之间使用大部分逻辑,“模型”用作UI与之交互的业务逻辑的抽象。

从这个角度来看,我认为你真正想要的是一个控制多个视图的视图模型(VM)。这是一个相当典型的场景,首选方法(IMO无论如何)是拥有一个分层视图模型,它具有顶级应用程序模型和一些代表UI中不同组件的子VM,尽管您可以将所有内容绑定到您的如果你真的想要顶级VM。

要做到这一点,我们首先要定义我们的视图模型

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}}"/>