前言
WPF
是Microsoft
在.NET
平台下支持使用mvvm方式设计应用及其界面的一个优秀框架,本次项目的目的是使用WPF构建一个简单的家电厂家商用演示程序。使用.NET4.7
和Panuon.UI
框架搭建。
基本用法
WPF
是使用.xaml
( eXtensible Application Markup Language )文件对界面进行设计的,xaml
是xml
在应用上的变体,他的通常由引用和标记组成。
<Window x:Class="project.wpf.f.icooling._2002.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="clr-namespace:Panuon.UI.Silver;assembly=Panuon.UI.Silver"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
Title="主界面" Height="600" Width="1000">
<Grid>
<Button Height="30"
Width="200"
Content="Button"
pu:ButtonHelper.ButtonStyle="Standard"
pu:ButtonHelper.CornerRadius="5"
pu:ButtonHelper.IsWaiting="{Binding loading}"></Button>
</Grid>
</Window>
xmlns
表示命名空间,xmlns:pu
表示将后续值指定为pu
这个自定义名称的命名空间。
Grid
是WPF
的默认初始化节点,表示布局的开始,也是定义行列的基本样式。
<Button/>
是布局中的一个控件,并且此控件的样式、属性、操作等受其内部的标记所控制。
在上述代码块中,定义了一个基本的布局并展示一个按钮,此按钮的IsWaiting
属性受loading
属性控制(绑定)。
架构
本项目使用的是经典的MVVM
架构方式,即Model
、View
、ViewModel
。
Model
用于管理所有的对象模型,在较为大型的项目中通常会使用Repository
和Services
层进行中间管理,使得数据库和应用之间的耦合降低。
ViewModel
是Model
和UI
之间交互的桥梁,用于将数据绑定到对应的UI
上,降低开发人员管控界面的成本 。
View
UI层,.xaml
布局文件。
布局
Column/Row Definitions
使用Column/Row Definitions
进行分栏布局,GridSplitter
用于栏与栏之间的间隙定义。
<RowDefinition Height="10*"></RowDefinition>//10*表示相对布局,布局加权为10
<Button Grid.Column="0" Grid.Row="0" Content="布局到0列,0行"></Button>
<Button Grid.RowSpan="2" Content="这是一个占用2栏的按钮"></Button>
TreeView
示例样式
TreeView
是一个树状列表,可以用于作为菜单栏,其中pu:TreeViewHelper
是框架自带的快捷设置属性的方式,BasedOn
表示继承一个控件的样式,使得默认的MenuItem
变成资源文件里面的MenuItem
。
<TreeView x:Name="TvMenu"
Grid.Row="0"
pu:TreeViewHelper.SelectedForeground="#49A9C0"
pu:TreeViewHelper.ExpandMode="SingleClick"
pu:TreeViewHelper.SelectMode="ChildOnly"
SelectedItemChanged="TvMenu_SelectedItemChanged"
ItemsSource="{Binding MenuItems}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}"
BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="Visibility"
Value="{Binding Visibility}" />
<Setter Property="pu:TreeViewHelper.ItemIcon"
Value="{Binding Icon}" />
<Setter Property="IsExpanded"
Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding Path=Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
此项目中,我们因为需要将菜单栏设置为横向布局,故使用TabControl
作为组件。同时在构造函数中将子视图/控件载入到缓存,加载到目标DataContext
中。
public MainWindow()
{
InitializeComponent();
var list = new ObservableCollection<TabControllViewItemModel>() {
new TabControllViewItemModel("主页","Splash","\uf05a"),
new TabControllViewItemModel("机柜空调","Device","\uf05a"),
new TabControllViewItemModel("风扇过滤器","Calendar","\uf05a"),
new TabControllViewItemModel("加热器","tag3","\uf05a"),
new TabControllViewItemModel("水热交换器","tag3","\uf05a"),
new TabControllViewItemModel("冷凝水蒸发器","tag3","\uf05a"),
};
ViewModel = new MainWindowViewModel(list);
DataContext = ViewModel;
}
/// <summary>
/// 用户更改界面
/// </summary>
/// <param name="sender"></param>
/// <param name="