C# WPF

会有一股神秘感。 提交于 2020-07-26 15:43:39

前言

本文主要讲解采用WPF MVVM模式设计OPC Client的过程,算作对于WPF MVVM架构的学习记录吧!不足之处请不吝赐教,感谢!

涉及知识点

  • C#基础
  • Xaml基础
  • 命令、通知和数据绑定
  • Prism+Blend
  • MahApps.Metro(第三方框架)
  • OPC

项目实现功能

  • 用户登陆(模拟登陆过程,未连接数据库)
  • OPC同步读写、异步读写操作等

开发环境

  • Window 10
  • Visual Studio 2019
  • .Net Framework 4.8

成品效果图

项目详解

MVVM框架搭建

为了节省开发时间,在事件绑定上使用了Prism框架,OPC通信方面使用了OPCDAAuto.dll类库,二者均可以通过Nuget方式安装到项目中。

  • 定义了一个DelegateCommand类用来处理属性和命令;
  • 定义了一个NotificationObject类用来通知属性和命令的改变;

注意:在使用事件绑定时,需要添加引用 xmlns:i="http://schemas.microsoft.com/xaml/behaviors",然后根据控件对应事件的名称设置绑定命令即可。

比如我们想给ComboBox的SelectionChanged事件设置一个事件绑定,可这么写

xaml代码:

<ComboBox
    x:Name="CombServerList"
    Width="120"
    Margin="{StaticResource ControlMargin}"
    ItemsSource="{Binding ServerList}">
    <!--  事件绑定  -->
    <i:Interaction.Triggers>
          <i:EventTrigger EventName="SelectionChanged">
             <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=CombServerList}" />
          </i:EventTrigger>
     </i:Interaction.Triggers>

</ComboBox>
View Code

VM代码:

public ICommand SelectionChangedCommand
        {
            get
            {
                return new Prism.Commands.DelegateCommand<ComboBox>((combobox) =>
                {
                   // 业务逻辑
                });
            }
        }
View Code

相关类的定义代码如下:

public class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 判断判断命令是否可以被执行
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            if (this.CanExecuteFunc != null)
            {
                this.CanExecuteFunc(parameter);
            }
            else
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 执行相关的函数或者命令
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            if (this.ExecuteAction != null)
            {
                this.ExecuteAction(parameter);
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 声明一个委托用来执行命令对应的方法
        /// </summary>
        public Action<object> ExecuteAction { get; set; }

        /// <summary>
        /// 声明一个方法,用来判断命令是否可以被执行
        /// </summary>
        public Func<object, bool> CanExecuteFunc { get; set; }

    }
DelegateCommand
public class NotificationObject : INotifyPropertyChanged
    {
        /// <summary>
        /// 实现接口
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 通知属性的改变
        /// </summary>
        /// <param name="propertyName"></param>
        public void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
NotificationObject

UI界面搭建

这里主要采用第三方开源框架MahApps.Metro,可以通过NuGet方式安装到项目中,这里不再展开讲解,感兴趣的朋友可以参考 MahApps.Metro - Quick Start

OPC相关处理

大致分为如下几步:

  • 获取OPC服务列表
  • 连接OPC服务
  • 创建分组
  • 获取项目列表
  • 添加项目到分组中
  • 对项目的内容进行读写操作

比较简单,不再展开了。

登陆界面

这里我们说一说登陆界面的实现,由于追求PURE MVVM,所以这里有三点需要说明一下:

  • PasswordBox绑定
  • 圆形头像
  • 登陆窗体切换

PasswordBox绑定:自定义帮助类,使用PasswordBoxBehavior实现绑定;

圆形头像:自定义样式,增加Image圆角属性;

登陆窗体切换:借助prism的shell。

至此,已全部结束。

  作者:Jeremy.Wu
  出处:https://www.cnblogs.com/jeremywucnblog/
  本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!