如何在WPF多任务UI中使用模板



我是WPF的新手,但我尽我所能努力学习。请帮我克服一个我现在正在努力解决的问题。我正在构建一个多任务UI,其中每个选项卡都应该有完全相同的控件布局。同时,在一个选项卡中也有重复的控件块(标签组)。控件的内容将由来自外部源的数据填充——显然,我将使用数据对象的实例将它们绑定到选项卡项的DataContext属性:每个选项卡项一个实例。我的问题是,我不知道如何通过使用模板来优化代码。我想我应该使用两个不同的模板,一个在选项卡内,另一个用于整个选项卡,对吧?但是如何绑定数据呢?在xaml标记下面,我将用于每个选项卡和后面的代码,这样您就可以了解这个想法。带有数字内容的标签应绑定到对象实例(PLC)的特性。

XAML:

<Window x:Class="WpfPromholComplementary_1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc = "clr-namespace:WpfPromholComplementary_1"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:dvc="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"
Title="Window2" Height="800" Width="1000">  
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="210" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="0" BorderThickness="1" BorderBrush="Blue" Margin="2" CornerRadius="8,8,8,8">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 1" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="1" BorderBrush="Blue" >
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 2" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="2" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 3" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="3" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 4" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="4" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 5" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="5" BorderThickness="1" BorderBrush="Blue">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="Module 6" Grid.Row="1" Grid.ColumnSpan="2" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="2" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="3" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="4" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="123.4" Grid.Row="5" Grid.Column="1" Height="Auto" Width="Auto" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" Grid.Column="0" Height="Auto" Width="Auto" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<StackPanel Margin="5,5,5,5"  Grid.Row="3" Grid.ColumnSpan="4">
<WindowsFormsHost>
<dvc:Chart x:Name="chart" />
</WindowsFormsHost>
</StackPanel>
<StackPanel Grid.Row="0" Grid.ColumnSpan="6" Orientation="Horizontal">
<Label Content="IP-address:" Height="33" Width="Auto" FontSize="20" Padding="5,0,5,5"/>
<Label Content="192.168.1.10" Height="33" Width="Auto" FontSize="20" Padding="5,0,5,5"/>
</StackPanel>
<DataGrid x:Name="dgDataGrid" Grid.Row="4" Grid.Column="4" Grid.ColumnSpan="2" IsSynchronizedWithCurrentItem="False"/>
</Grid>

代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing;
namespace WpfPromholComplementary_1
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
PLC plc1 = new PLC { ID = 1, Module_Number = "1", Channel_1 =  "1234", Channel_2 = "5678", Channel_3 = "9012", Channel_4 = "3456" };
this.DataContext = plc1;
}
}
}

我必须决定分两部分回答。其中一部分将在代码隐藏方法中清晰可见,另一部分则在MVVM(模型视图视图模型)中。

格式化窗口上侧的最佳想法是使用相同的组件,在该组件中您将定义源,而不是模板化。模板在某些地方很有用,在这些地方你有一个控件,并且你想改变它的外观(控件的布局)。

首先,您应该创建自己的UserControl(我在示例中称之为MyModuleFrame):

XML:

<UserControl x:Class="WpfPromholComplementary_1.MyModuleFrame"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:local="clr-namespace:WpfPromholComplementary_1"
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="300"
x:Name="mUserControl">
<Border BorderThickness="1" BorderBrush="Blue" CornerRadius="8,8,8,8">
<Grid Background="LightCyan">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Label Content="{Binding ItemSource.Number, ElementName=mUserControl}" Grid.Row="1" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch1, ElementName=mUserControl}" Grid.Row="2" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch2, ElementName=mUserControl}" Grid.Row="3" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch3, ElementName=mUserControl}" Grid.Row="4" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="{Binding ItemSource.Ch4, ElementName=mUserControl}" Grid.Row="5" Grid.Column="1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 1:" Grid.Row="2" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 2:" Grid.Row="3" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 3:" Grid.Row="4" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Label Content="Channel 4:" Grid.Row="5" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</UserControl>

C#:

namespace WpfPromholComplementary_1
{
/// <summary>
/// Interaction logic for MyModuleFrame.xaml
/// </summary>
public partial class MyModuleFrame : UserControl
{
public MyModuleFrame()
{
InitializeComponent();
}
public Module ItemSource
{
get { return (Module)GetValue(ItemSourceProperty); }
set { SetValue(ItemSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemSourceProperty =
DependencyProperty.Register("ItemSource", typeof(Module), typeof(MyModuleFrame), new PropertyMetadata(default(Module)));
}
}

将所有UserControls的属性定义为DependencyProperty是非常重要的为什么因为WPF正在使用它们来执行与视图处理相关的所有操作。在初始化时,它们被注册在WPF框架&一旦有人想要访问它们,他们就会调用WPF(返回值的人),而不是直接方法。

一旦定义了控件,就可以在窗口中使用它。我从一开始就删除了一些代码(我没有参考资料)&结束代码只是这样你有一个想法:

<Window x:Class="WpfPromholComplementary_1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc = "clr-namespace:WpfPromholComplementary_1"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="Window2" Height="800" Width="1000">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="210" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="0" ItemSource="{Binding Module1}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="1" ItemSource="{Binding Module2}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="2" ItemSource="{Binding Module3}"/>
<loc:MyModuleFrame Grid.Row="1" Grid.Column="3" ItemSource="{Binding Module4}"/>
<!-- other modules & stuff-->
</Grid>
</Window>

一旦你达到上面的点,你需要获得动态数据,可以通过三种方式获得:

  • 通过从代码后面插入(Win-forms方法,例如:TextBox1.ModuleNumber="3"-不太抽象,不用于大型应用程序)
  • 通过绑定到代码背后(在代码背后定义属性,将窗口的dataContext设置为this)
  • 通过绑定到视图模型(遵循MVVM模式)-这里有一些教程

根据选择的选项,您必须更新上面的代码。

此外,我们应该为我们的应用模块类定义Model。下面的代码不支持视图更新。要获得支持,您必须实现INotifyPropertyChanged接口(详细信息如下):

//Simplified
public class Module
{
public string Number { get; set; }
public double Ch1 { get; set; }
public double Ch2 { get; set; }
public double Ch3 { get; set; }
public double Ch4 { get; set; }
}

视图模型:

public class MainViewModel
{
public Module Module1 { get; set; } = new Module()
{
Number = "1",
Ch1 = 123.4,
Ch2 = 123.4,
Ch3 = 123.4,
Ch4 = 123.4
};
/* other modules... */
}

MVVM方法:

应用程序配置:

<Application x:Class="WpfPromholComplementary_1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfPromholComplementary_1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<local:MainViewModel x:Key="MainViewModel"/>
</Application.Resources>
</Application>

代码隐藏方法:

查看.cs:

public partial class Window
{
public Window()
{
InitializeComponent();
this.DataContext = this;
}
public Module Module1 { get; set; } = new Module(); //in this case You do not need ViewModel
}

此时您应该有一个工作应用程序,在那里您不能更改任何内容

现在有两种方法可以更新View中的值,一种是遵循MVVM的正确方式,另一种是在代码隐藏中再次更新。我将描述两者仅供参考:

首先,您的模块需要从INotifyPropertyChange继承(仅针对2个属性的示例):

using System.ComponentModel;
public class Module : INotifyPropertyChanged
{
private string _number;
public string Number
{
get { return this._number; }
set
{
if (_number == value) return;
_number = value;
OnPropertyChanged(nameof(Number));
}
}
private double _ch1;
public double Ch1
{
get { return this._ch1; }
set
{
if (_ch1 == value) return;
_ch1 = value;
OnPropertyChanged(nameof(Ch1));
}
}

//other channels fits there
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string aNameOfProperty)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(aNameOfProperty));
}
}

代码隐藏:

现在假设我们要处理一个事件到按钮点击(XML):

<Button Click="MyButton_Click"/>

在代码背后,我们可以做(C#):

private void MyButton_Click(object sender, MouseEventArgs e)
{
//Your ViewModel is stored in DataContext, You can just cast to approach properties
var VM = (this.DataContext as MainViewModel);
VM.Module1.Number = "Module Number Xyz";
}

MVVM:MVVM方法有点困难,因为您需要在某些命令类上实现ICommand接口,请参阅中继命令以供参考。

一旦你有了这个,XML:

<Button Command="{Binding DoSomeWorkCmd}"/>

在您的视图中模型:

private ICommand _DoSomeWorkCmd;
public ICommand DoSomeWorkCmd
{
get
{
if (_DoSomeWorkCmd != null) return _DoSomeWorkCmd;
_DoSomeWorkCmd = new RelayCommand((object aParam)=> { return true; }, (object aParam) =>
{
this.Module1.Number = "MyNewNumber XyZ";
});
return this._DoSomeWorkCmd;
}
}

整个解决方案的MVVM示例可以在我的GIT上下载:https://github.com/Tatranskymedved/WpfPromholComplementary_1

最新更新