过节闲着无聊,做了一个和上位机开发有关的小测试。
上位机的开发有BS和CS模式,我个人倾向CS,采用.Net上的WPF,可以做漂亮界面。
软件开发存在多种设计模式,这里是用一个小实验来测试和学习一下时下流行的MVVM开发模式。
在MVVM模式下,UI(也就是View)是完全和后台剥离的,只通过底层暴露的接口与后台关联。UI只与视觉和交互有关,界面的数据结构被抽象为ViewModel。这样的好处是结构的清晰简化、可扩展性和可维护性很好,尤其是UI的可变化性非常灵活。ViewModel和后台业务,也就是Model、Service 和数据库,进行交互。和PLC的通信属于Service的一部分。
其实类似的分离设计模式MVC、MVP等也有一些,MVVM的关键点就在于:ViewModel是和界面去耦合的,它通过事件发布接口数据的变化,而不去调用界面。
MVVM模式的精华部分就在View和ViewModel之间的关系处理,底层业务Model部分其实和其它的分离开发模式一样。在这个简单的小例子中只测试了View和ViewModel之间的实现,没有涉及任何底层的业务,为的是关注重点。
1、View部分的代码:这个小测试采用的界面很简单,几个滑杆用于体现数值变化,几个按钮。数值输入,加法结果返回。还有其它几个命令按钮。
<Window x:Class="WpfApp01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp01"
xmlns:vm="clr-namespace:WpfApp01.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Menu>
<MenuItem Header="_Save" Command="{Binding CommandPopDiag}" IsEnabled="{Binding EnableFlag}" />
</Menu>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="slider1" Grid.Row="0" Background="LightBlue" Minimum="-100" Maximum="100" Margin="4"
Value="{Binding Input1}"/>
<Slider x:Name="slider2" Grid.Row="1" Background="LightBlue" Minimum="-100" Maximum="100" Margin="4"
Value="{Binding Input2}"/>
<Slider x:Name="slider3" Grid.Row="2" Background="LightBlue" Minimum="-100" Maximum="100" Margin="4"
Value="{Binding Result}"/>
<Button x:Name="addButton" Grid.Row="3" Content="Add" Width="120" Margin="42,20,355,158"
Command="{Binding CommandAdd}" IsEnabled="{Binding EnableFlag}"/>
<Button x:Name="MsgButton" Grid.Row="3" Content="Msg" Width="120" Margin="185,20,212,158"
Command="{Binding CommandMsg}" CommandParameter="20" IsEnabled="{Binding EnableFlag}"/>
<Button x:Name="Button2" Grid.Row="3" Content="b" Width="120" Margin="337,20,60,158"
Command="{Binding ButtonCommand2}" IsEnabled="{Binding EnableFlag}"
CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
<Button x:Name="LockButton" Grid.Row="3" Content="Lock" Width="120" Margin="185,129,212,48"
Command="{Binding CommandEnable}" />
</Grid>
</Grid>
</Window>