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.…

谷歌云使用账号密码_如何使用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提供了一种…

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.…

保存网络文章以供以后使用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…

我们生活在最好的时代

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驱动…

使用高级管理控制台获得对Windows Home Server的扩展访问

Windows Home Server is easy to setup and use so anyone with basic computer knowledge can operate their own server. But what if you’re an advanced user and want more control over various administrative functions? The Advanced Admin Console Addin gives you…

变动性算法源代码分析与使用示例(copy_backward、 transform、 replace_copy_if 等)

首先回顾前面的文章&#xff0c;我们把for_each 归类为非变动性算法&#xff0c;实际上它也可以算是变动性算法&#xff0c;取决于传入的第三个参数&#xff0c;即函数 指针。如果在函数内对容器元素做了修改&#xff0c;那么就属于变动性算法。 变动性算法源代码分析与使用示例…

如何在Outlook中的电子邮件上显示快速操作按钮

There are probably actions you regularly perform in Outlook, such as deleting, archiving, and marking things as read. Here’s how to use Quick Action buttons to add one-click options that appear over every email to perform each action. 您可能会在Outlook中定…

使用RestTemplate时报错java.lang.IllegalStateException: No instances available for 127.0.0.1

我在RestTemplate的配置类里使用了 LoadBalancedComponentpublic class RestTemplateConfig { Bean LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }}或者 再调用Autowiredprivate RestTemplate restTemplate;必须使用应用名作为代替ip:端口&a…

zune linux_更新您的Zune Player软件

zune linuxKeeping your computer and software up to date is very important in keeping everything running smooth and secure. It’s also important to keep your geeky gadgets updated as well. Here we take a look at updating a Zune HD. 保持计算机和软件的最新状态…

写一个简单的 django_post demo

1.新建一个django工程&#xff0c;其路由为下图 2.要做的是一个 简单的登录请求&#xff0c;以表单形式提交&#xff0c;html 部分代码如下 这里注意action指向的是路由的地址&#xff0c;index1后的views.login部分代码如下 这段代码指的是&#xff0c;如果login接收到的请求是…

日志收集

2019独角兽企业重金招聘Python工程师标准>>> ELK (ElasticSearch、Logstash、Kibana)&#xff1a; https://my.oschina.net/itblog/blog/547250 转载于:https://my.oschina.net/zfscofield/blog/1625703

autocopy2u_借助AutoCopy简化Firefox中的文本复制和粘贴

autocopy2uLooking for an easy way to speed up copying and pasting in Firefox? Now you can reduce the amount of work that you have to do by half with AutoCopy. 是否在寻找一种简便的方法来加快Firefox中的复制和粘贴&#xff1f; 现在&#xff0c;您可以使用自动复…

僵尸进程处理方式

Linux服务器上&#xff0c;多少会出现一些僵尸进程&#xff0c;下面介绍如何快速寻找和消灭这些僵尸进程的方法 首先&#xff0c;我们可以用top命令来查看服务器当前是否有僵尸进程&#xff0c;在下图中可以看到僵尸进程数的提示&#xff0c;如果数字大于0&#xff0c;那么意味…

chromebook刷机_如何查看Chromebook的停产日期

chromebook刷机Google谷歌There comes a time in your Chromebook’s life when it no longer receives updates from Google. It’s inevitable and could be a lot sooner than you think. Here’s how to see your Chromebook’s scheduled end-of-life date. Chromebook一生…