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