WPF项目学习.一

WPF项目搭建

版权声明:本文为博主初学经验,未经博主允许不得转载。

一、前言

   记录在学习与制作WPF过程中遇到的解决方案。

   使用MVVM的优点是 数据和视图分离,双向绑定,低耦合,可重用行,相对独立的设计和逻辑;

 

二、配置

系统环境:win10

开发工具:Visual Studio 2017

开发语言:C#.WPF (MVVM框架)

数据库:SQLiteStudio

 

三、附件

  • vs_enterprise.exe   在线安装 Visual Studio 2017 开发工具;
  • SQLiteStudio.zip     免安装Sqlite轻量数据库操作工具;
  • WPF-MVVM-Work.zip 项目源代码;

四、步骤

  1. 创建项目;

    

  2. 文件夹层级;

  建文件夹:Model, ViewModel, View, Resources, Lib, Service, Common;

Model是模型层,属性类存放的地方;也就是存放不涉及业务逻辑的代码;

  例如:列表元素,接口参数,枚举,数据交互的参数模型和View基础元素属性等等;

ViewModel是视图模型层,是MVVM实现业务逻辑代码的地方;

  例如:操作视图界面数据的呈现,界面按钮触发的事件和操作数据库前后对界面交互的事件;

View是视图层,是窗体布局实现的地方;也就是呈现给用户交互使用的界面窗体;

  例如:登录页面,查询页面,新增和编辑的页面等;

Resources是资源库层,里面存放声音,图片和样式布局等统一调用外部资源的地方;

Lib是引用层,放置一些第三方引用便于调用,也可以用nuget统一管理第三方dll;

Service是服务层,是实现对数据库或者对站点接口的操作,进行数据持久化和数据交互;

Common是工具层,是存放一些公共的代码,统一调用,简洁业务逻辑代码的冗余;

    注:可以建文件夹,但更推荐新建类库放置以上层级;

    

  3. 控件的使用与布局;

    3.1 从工具箱中直接拖拉控件;

      

    3.2 直接在代码中编辑控件代码;

      

  4. 代码关联;

    4.1 View与ViewModel的交互关联:

      - View后台的代码关联

     public MainWindow() //类名
        {InitializeComponent();
       //后台代码有这句就实现了View和ViewModel的绑定DataContext
= new MainWindowViewModel();
     }

 

      - 文本的绑定 

     前端:<TextBox Text="{Binding TxtInput}"/>
     后端:

        public string TxtInput
        {
          get => _txtInput;
          set
          {
            _txtInput = value;

            //用RaisePropertyChanged刷新前端绑定控件的输入框文本内容
            RaisePropertyChanged("TxtInput"); 
          }
        }

        private string _txtInput;

 

      - 事件的绑定

     前端:<Button Content="添加" Command="{Binding BtnAddContent}"/>
     后端:

        public MainWindowViewModel() 
        {

          //按钮事件与业务的衔接   也可以在BtnAddContent的Set中写
          BtnAddContent = new RelayCommand(AddContent);
        }

        //前端绑定的 添加按钮 Command事件

        public RelayCommand BtnAddContent { get; set; }

        private void AddContent()
        {
           //按钮事件处理的业务逻辑代码
        }

 

      - 样式的绑定

      <TextBox Style="{StaticResource TxbTrigger}" Tag="序号..." /><Button Content="添加" Template="{StaticResource DefaultButton}" />

”TxbTrigger是输入框水印样式资源,DefaultButton是按钮样式资源模板;详细样式代码,查阅源码中的Resources-Style;“

    4.2 数据绑定和命令绑定的代码(如果用第三方框架引用,就不需要编写以下两个方法类)
  //数据绑定
  public
class ViewModelBase : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;protected void RaisePropertyChanged<T>(Expression<Func<T>> action){var propertyName = GetPropertyName(action);RaisePropertyChanged(propertyName);}private static string GetPropertyName<T>(Expression<Func<T>> action){var expression = (MemberExpression)action.Body;var propertyName = expression.Member.Name;return propertyName;}public void RaisePropertyChanged(string propertyName){if (PropertyChanged != null)PropertyChanged(this,new PropertyChangedEventArgs(propertyName));}}
  //命令绑定
  public
class RelayCommand : ICommand{public Action ExecuteAction; //执行方法public Action<object> ExecuteCommand; //执行方法 带参数public Func<object, bool> CanExecuteCommand; //执行方法的条件public RelayCommand(Action action)// 执行事件 {ExecuteAction = action;}
     //执行带参数的事件
public RelayCommand(Action<object> action) {ExecuteCommand = action;}
     //根据条件执行带参数的事件
public RelayCommand(Action<object> action, Func<object, bool> can) {ExecuteCommand = action;CanExecuteCommand = can;}
     //当命令可执行状态发生改变时,应被激活
public event EventHandler CanExecuteChanged;
     //用于判断命令是否可以执行
     public bool CanExecute(object parameter) {if (ExecuteAction != null) return true;return CanExecuteCommand == null || CanExecuteCommand(parameter);}
     //命令执行
public void Execute(object parameter) {if (ExecuteCommand != null) ExecuteCommand(parameter);else ExecuteAction();}}

ViewModel的业务类需要继承ViewModelBase

  public class MainWindowViewModel : ViewModelBase

前端的DataGrid绑定的数据需要用ObservableCollection类型定义列表;

     public ObservableCollection<AddModel> AddContent{get => _addContent;set{_addContent = value;RaisePropertyChanged("AddContent"); 
            }}private ObservableCollection<AddModel> _addContent =
                  new ObservableCollection<AddModel>();

"AddModel"是Model中的属性类;代表DataGrid中绑定的列名指向;

DataGrid前端代码:

<DataGrid x:Name="DgTimes" 
  ItemsSource="{Binding AddContent}" AutoGenerateColumns="False"SelectedItem="{Binding SelectTime,UpdateSourceTrigger=PropertyChanged}"><DataGrid.InputBindings>
    <!--双击事件--><MouseBinding Gesture="LeftDoubleClick" Command="{Binding DgDoubleClick}" CommandParameter="{Binding ElementName=DgTimes,Path=SelectedItem}"/><!--单击事件,也可以在SelectedItem选中事件中的set属性编辑业务代码-->
  <MouseBinding Gesture="LeftClick" Command="{Binding DgClick}"CommandParameter="{Binding ElementName=DgTimes,Path=SelectedItem}"/></DataGrid.InputBindings><DataGrid.Columns><DataGridTextColumn Header="序号" Binding="{Binding RowIndex}"/><DataGridTemplateColumn Header="勾选?" MinWidth="30"><DataGridTemplateColumn.CellTemplate><DataTemplate><Grid>
             <!--图片的绑定,注意不能为null或者空值,不然会加载超慢--><Image Width="20" Height="20" Source="{Binding Photo}"/></Grid></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn><DataGridTextColumn Header="输入内容" Binding="{Binding AddContent}"/><DataGridTextColumn Header="时间" Binding="{Binding AddTime}"/></DataGrid.Columns> </DataGrid>

 注:由于整个制作项目的操作视频文件过大,如有所需,留邮箱地址给博主;

  5. 执行效果;

 

五、注意事项

本次项目制作并没有使用数据库的操作;源代码中也是没有!

源码中包括了对输入框限制数字的输入方法;

源码中包括了Button,TextBox,CheckBox,DataGrid等等样式资源代码;

有些网友推荐 MVVMLight 或者 Prism 等第三方MVVM框架引用;

 

 六、下篇预告

在制作WPF过程中遇到的问题以及解决方案;

其中包括:焦点的控制,键盘事件触发,输入框的数字限制,异步处理,隐藏状态可用状态,自定义属性等等...

 

 

转载于:https://www.cnblogs.com/yjwlogs/p/8459751.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/278415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

airpods_如何通过AirPods与其他人共享音乐

airpodsKhamosh PathakKhamosh PathakUsing the new Audio Sharing feature introduced in iOS 13.1 and iPadOS 13.1, you can share audio from one iPhone with two AirPods. You can watch a video or listen to a song along with your friend in just a tap! 使用iOS 13.…

Laravel 5 多个视图共享数据的方法

我们都知道模板一般会用到继承&#xff0c;导航栏就是一个很好的例子&#xff0c;但是导航栏的数据如何共享&#xff0c;比如有个导航的文件叫在view/navigation.blade.php为了简单一点&#xff0c;文件里只有设置了一个变量1{{ $cqh }}现在的要求是每个页面都会用到这个变量&a…

HR面 - 十大经典提问

1、HR&#xff1a;你希望通过这份工作获得什么&#xff1f; 1&#xff09;、自杀式回答&#xff1a;我希望自己为之工作的企业能够重视质量&#xff0c;而且会给做得好的员工予以奖励。我希望通过这份工作锻炼自己&#xff0c;提升自己的能力&#xff0c;能让公司更加重视我。 …

谷歌云使用账号密码_如何使用Google密码检查

谷歌云使用账号密码Google has a tool designed to securely analyze your passwords against a database of ones that are known to be compromised and breached. Password Checkup is available as an extension or a web service. Here’s how to use it. Google提供了一种…

HTML特殊字符编码对照表

HTML特殊字符编码对照表 特殊符号命名实体十进制编码特殊符号命名实体十进制编码特殊符号命名实体十进制编码Α&Alpha;Β&Beta;Γ&Gamma;Δ&Delta;Ε&Epsilon;Ζ&Zeta;Η&Eta;Θ&Theta;Ι&Iota;Κ&Kappa;Λ&Lambda;Μ&Mu;Ν&a…

CentOS 7.0下使用yum安装MySQL

CentOS7默认数据库是mariadb,配置等用着不习惯,因此决定改成mysql,但是CentOS7的yum源中默认好像是没有mysql的。为了解决这个问题&#xff0c;我们要先下载mysql的repo源。1.下载mysql的repo源$ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm2.安装my…

Jolicloud是一款适合上网本的漂亮新操作系统

Want to breathe new life into your netbook? Here’s a quick look at Jolicloud, a unique new Linux based OS that lets you use your netbook in a whole new way. 想为您的上网本注入新的活力吗&#xff1f; 快速浏览一下Jolicloud&#xff0c;这是一个独特的基于Linu…

Repeater片段

1.字段过长截取字符串 1.1 截取字符串类 可以直接substring 也可以<%# Utility.Common.GetShow( Eval("NewTitle").ToString(),20,true) %><td><%#fcwms.Common.GetContent.GetShow(Eval("com_address").ToString(), 19, true)%> </t…

谷歌浏览器的翻译功能在哪_如何在Google表格中使用AND和OR功能

谷歌浏览器的翻译功能在哪If you’ve ever wanted to check whether data from your Google Sheets spreadsheet meets certain criteria, you can use AND and OR. These logical functions give you TRUE and FALSE responses, which you can use to sort through your data.…

Reptile:requests + Xpath 爬取段子网的段子

2019/1/24 中午路飞学成 爬虫课程 实验及笔记。 Xpath是路飞爬虫课程中老师说的三种解析方式之一&#xff0c;前面是re正则表达式的解析方式&#xff0c;现在是xpath的解析方式&#xff0c;后面还有一个是bs4的解析方式。 re其实我理解的很困难&#xff0c;而且到现在都还不怎么…

Android 系统权限

Android 是一个权限分隔的操作系统&#xff0c;其中每个应用都有其独特的系统标识&#xff08;Linux 用户 ID 和组 ID&#xff09;。系统各部分也分隔为不同的标识。Linux 据此将不同的应用之间、应用与系统之间分隔开来 ##一、安全架构 Android 安全架构的中心设计点是&#x…

【转载】负数的二进制

https://jingyan.baidu.com/article/29697b9106eb52ab21de3c7a.html 将十进制的负数变成二进制数的过程&#xff1a; 1.写出绝对值的二进制码&#xff08;原码&#xff09; 2.取反&#xff08;反码&#xff09; 3.1,&#xff08;补码&#xff09; 同理&#xff0c;将二进制的负…

保存网络文章以供以后使用Instapaper阅读

Have you ever come across a bunch of great articles that you want to read online, but just don’t have the time? Today we take a look at an online service that allows you to read your articles later, either online, or on an iPhone, or eReader. 您是否曾经遇…

谷歌chrome xp_将非Google任务列表添加到Chrome

谷歌chrome xpMost people rely on a task list to help them remember what they need to do but not everyone wants one that is tied to a Google account. If you have been wanting an independent tasks list then join us as we look at the Tasks extension for Googl…

学习笔记 - MarkDown 语法

学习参考网址&#xff1a;https://www.appinn.com/markdown/index.html # **gitskill**## 标题 ># 这是 H1 >## 这是 H2 >###### 这是 H6## 区块引用 Blockquotes > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipisci…

[BZOJ4671]异或图

description BZOJ 定义两个结点数相同的图\(G1\)与图\(G2\)的异或为一个新的图\(G\), 其中如果\((u,v)\)在\(G1\)与\(G2\)中的出现次数之和为\(1\), 那么边\((u,v)\)在\(G\)中, 否则这条边不在\(G\)中. 现在给定\(s\)个结点数相同的图\(G1...s\),设\(S{G1,G2,...,Gs},\) 问\(S\…

我们生活在最好的时代

2019独角兽企业重金招聘Python工程师标准>>> 没规划的人生叫拼图&#xff0c;有规划的人生叫蓝图&#xff1b; 没目标的人生叫流浪&#xff0c;有目标的人生叫航行&#xff01; 我们生活在最好的时代&#xff1a;在认知和学习机会上&#xff0c;人人平等&#xff0c…

MapReduce详解和WordCount模拟

最早接触大数据&#xff0c;常萦绕耳边的一个词「MapReduce」。它到底是什么&#xff0c;能做什么&#xff0c;原理又是什么&#xff1f;且听下文讲解。 是什么 MapReduce 即是一个编程模型&#xff0c;又是一个计算框架&#xff0c;它充分采用了分治的思想&#xff0c;将数据处…

无法创建系统映像_如何创建USB驱动器的映像

无法创建系统映像You can back up your USB drive by creating a saved image. You can then take that saved image and clone multiple USB sticks. This guide shows you how to create an image of your USB drive using Windows 10. 您可以通过创建保存的图像来备份USB驱动…

UGUI事件之Drag拖拽事件

UI事件之Drag拖拽事件2.UGUI 事件命名空间   当我们需要使用 UGUI 中的事件的时候&#xff0c;需要在脚本内引入专有命名空间&#xff1a;   using UnityEngine.EventSystems;----------------------------------2.拖拽相关事件接口----------------------------------1.三…