C# WPF数据绑定方法以及重写数据模板后数据绑定

写在前面

本文将会介绍WPF如何实现前后端数据绑定和在进行数据绑定时常用的方法和类以及对于DataGrid、ListView这样的控件重写数据模板后控件如何进行数据绑定

本文主要针对于数据绑定的基础实现进行介绍,通过此博文你将会有能力编写一个MVVM设计模式的C#、WPF项目。如果您是C#及WPF的资深开发人员本文可能对您没有太大的帮助,但如果你是一个正在学习和了解C#、WPF的开发人员来说本文可以帮助你认识MVVM设计模式和数据绑定。

 


 

一、实现前后端数据绑定:

说到前后端的数据绑定,就需要先说一下WPF的MVVM设计模式,它是由传统的MVC设计模式改进而来,不同点在于MVVM数据源更新不需要一个Controller控制器来向前台同步数据,同时前台数据更改也不需要控制器向后台同步。如果想深入详细的了解MVVM设计模式百度百科对这部分的讲解和说明我认为非常的详细和系统。也可以阅读下方的实例,相信通过代码实例更能够让你对MVVM有一个更深入的认识。

实例:

源代码地址(码云):https://gitee.com/hkb1202/csharp-wpf-data-binding-demo

实例基于.Net Core 3.1平台,为博主编写并亲测可用的,通过实例相信你可以更好的理解这部分内容。

C# WPF数据绑定方法以及重写数据模板后数据绑定

 

新建一个WPF项目,并且添加Command类和MainWindowsViewModel类

Command.cs代码:

C# WPF数据绑定方法以及重写数据模板后数据绑定

 1 using System;
 2 using System.Windows.Input;
 3 
 4 namespace WpfExample
 5 {
 6     public class Command : ICommand
 7     {
 8 
 9         /// <summary>
10         /// 检查命令是否可以执行的事件,在UI事件发生导致控件状态或数据发生变化时触发
11         /// </summary>
12         public event EventHandler CanExecuteChanged
13         {
14             add
15             {
16                 if (_canExecute != null)
17                 {
18                     CommandManager.RequerySuggested += value;
19                 }
20             }
21             remove
22             {
23                 if (_canExecute != null)
24                 {
25                     CommandManager.RequerySuggested -= value;
26                 }
27             }
28         }
29 
30         /// <summary>
31         /// 判断命令是否可以执行的方法
32         /// </summary>
33         private Func<object, bool> _canExecute;
34 
35         /// <summary>
36         /// 命令需要执行的方法
37         /// </summary>
38         private Action<object> _execute;
39 
40         /// <summary>
41         /// 创建一个命令
42         /// </summary>
43         /// <param name="execute">命令要执行的方法</param>
44         public Command(Action<object> execute) : this(execute, null)
45         {
46 
47         }
48 
49         /// <summary>
50         /// 创建一个命令
51         /// </summary>
52         /// <param name="execute">命令要执行的方法</param>
53         /// <param name="canExecute">判断命令是否能够执行的方法</param>
54         public Command(Action<object> execute, Func<object, bool> canExecute)
55         {
56             _execute = execute;
57             _canExecute = canExecute;
58         }
59 
60         /// <summary>
61         /// 判断命令是否可以执行
62         /// </summary>
63         /// <param name="parameter">命令传入的参数</param>
64         /// <returns>是否可以执行</returns>
65         public bool CanExecute(object parameter)
66         {
67             if (_canExecute == null) return true;
68             return _canExecute(parameter);
69         }
70 
71         /// <summary>
72         /// 执行命令
73         /// </summary>
74         /// <param name="parameter"></param>
75         public void Execute(object parameter)
76         {
77             if (_execute != null && CanExecute(parameter))
78             {
79                 _execute(parameter);
80             }
81         }
82     }
83 }

Command.cs

 Command类是实现ICommand接口,从而实现将前台的命令注册到后台的ViewModel中,在此不详细展开讲解,请先照抄代码,如果对这部分感兴趣可以查阅博客园中关于ICommand接口的详解。暂时不理解这里并不影响后续的编码。

MainWindowViewModel.cs代码:

C# WPF数据绑定方法以及重写数据模板后数据绑定

  1 using System.Collections.ObjectModel;
  2 using System.ComponentModel;
  3 using System.Windows;
  4 using System.Windows.Controls;
  5 
  6 namespace WpfExample
  7 {
  8     public class MainWindowViewModel : INotifyPropertyChanged
  9     {
 10         //实现接口当数据源变动通知前台UI
 11         public event PropertyChangedEventHandler? PropertyChanged;
 12 
 13         public void RaisePropertyChanged(string propName)
 14         {
 15             if (PropertyChanged != null)
 16             {
 17                 PropertyChanged(this, new PropertyChangedEventArgs(propName));
 18             }
 19         }
 20 
 21         /// <summary>
 22         /// 前台DataGrid绑定的People集合
 23         /// </summary>
 24         public ObservableCollection<Person> People { get; set; }
 25 
 26         /// <summary>
 27         /// 绑定前台DataGrid控件SelectedItem字段上,用于保存当前选中的Item所对应的数据源
 28         /// </summary>
 29         public Person SelectItem
 30         {
 31             get
 32             {
 33                 return m_SelectItem;
 34             }
 35             set
 36             {
 37                 m_SelectItem = value;
 38                 RaisePropertyChanged("SelectItem");
 39             }
 40         }
 41 
 42         /// <summary>
 43         /// DataGrid控件中删除按钮命令
 44         /// </summary>
 45         public Command DelClick
 46         {
 47             get
 48             {
 49                 if (m_DelClick == null)
 50                     m_DelClick = new Command(DeleteEvent);
 51 
 52                 return m_DelClick;
 53             }
 54         }
 55 
 56         /// <summary>
 57         /// 前台添加小刚按钮命令
 58         /// </summary>
 59         public Command AddClick
 60         {
 61             get
 62             {
 63                 if (m_AddClick == null)
 64                     m_AddClick = new Command(AdditionEvent);
 65 
 66                 return m_AddClick;
 67             }
 68         }
 69 
 70         /// <summary>
 71         /// 前台修改Text按钮命令
 72         /// </summary>
 73         public Command ReviseClick
 74         {
 75             get
 76             {
 77                 if (m_ReviseClick == null)
 78                     m_ReviseClick = new Command(ReviseEvent);
 79 
 80                 return m_ReviseClick;
 81             }
 82         }
 83 
 84         /// <summary>
 85         /// 前台TextBlock控件显示的文本
 86         /// </summary>
 87         public string TextInfo
 88         {
 89             get
 90             {
 91                 return m_TextInfo;
 92             }
 93             set
 94             {
 95                 m_TextInfo = value;
 96                 //数据源更新调用更新前台UI方法
 97                 RaisePropertyChanged("TextInfo");
 98             }
 99         }
100 
101         /// <summary>
102         /// DataGrid控件电话信息的TextBox键盘按下回车命令
103         /// </summary>
104         public Command PressEnterKey
105         {
106             get
107             {
108                 if (m_PressEnterKey == null)
109                     m_PressEnterKey = new Command(PressEnterKeyEvent);
110 
111                 return m_PressEnterKey;
112             }
113         }
114 
115         private Person m_SelectItem;
116         private Command m_DelClick;
117         private Command m_AddClick;
118         private Command m_ReviseClick;
119         private string m_TextInfo;
120         private Command m_PressEnterKey;
121 
122         /// <summary>
123         /// 构造方法
124         /// </summary>
125         public MainWindowViewModel()
126         {
127             People = new ObservableCollection<Person>();
128 
129             Person person1 = new Person() { Name = "小明", Age = 12, Sex = "", Phone = "110" };
130             Person person2 = new Person() { Name = "小红", Age = 13, Sex = "", Phone = "119" };
131             Person person3 = new Person() { Name = "小王", Age = 15, Sex = "", Phone = "120" };
132 
133             People.Add(person1);
134             People.Add(person2);
135             People.Add(person3);
136 
137             TextInfo = "点击右侧按钮这里内容将会变化!";
138         }
139 
140         /// <summary>
141         /// DataGrid控件中删除按钮事件
142         /// </summary>
143         /// <param name="obj">可传入前台控件</param>
144         private void DeleteEvent(object obj)
145         {
146             if (MessageBox.Show($"是否删除{SelectItem.Name}的数据?", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
147             {
148                 People.Remove(SelectItem);
149             }
150         }
151 
152         /// <summary>
153         /// 前台添加小刚按钮事件
154         /// </summary>
155         /// <param name="obj">可传入前台控件</param>
156         private void AdditionEvent(object obj)
157         {
158             if (MessageBox.Show("是否添加“姓名:小刚,年龄:18,性别:女,电话:123”?", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
159             {
160                 People.Add(new Person() { Name = "小刚", Age = 18, Sex = "", Phone = "123" });
161             }
162         }
163 
164         /// <summary>
165         /// 前台修改Text按钮事件
166         /// </summary>
167         /// <param name="obj">可传入前台控件</param>
168         private void ReviseEvent(object obj)
169         {
170             if (TextInfo == "点击右侧按钮这里内容将会变化!")
171             {
172                 TextInfo = "点击了右侧按钮!!!!!!!!!";
173             }
174             else
175             {
176                 TextInfo = "点击右侧按钮这里内容将会变化!";
177             }
178         }
179 
180         /// <summary>
181         /// DataGrid控件电话信息的TextBox键盘按下回车事件
182         /// </summary>
183         /// <param name="obj">可传入前台控件</param>
184         private void PressEnterKeyEvent(object obj)
185         {
186             TextBox textBox = (TextBox)obj;
187             MessageBox.Show($"点击了回车!控件内容为:{textBox.Text}");
188         }
189 
190         /// <summary>
191         /// 数据结构
192         /// </summary>
193         public class Person
194         {
195             public string Name { get; set; }
196             public int Age { get; set; }
197             public string Sex { get; set; }
198             public string Phone { get; set; }
199         }
200     }
201 }

MainWindowViewModel.cs

MainWindowsViewModel类中编写业务逻辑代码。

MainWindow.xaml代码:

C# WPF数据绑定方法以及重写数据模板后数据绑定

 1 <Window x:Class="WpfExample.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfExample"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="450" Width="800">
 9     <Grid>
10         <DataGrid Margin="10,10,10,50" ItemsSource="{Binding People, Mode=TwoWay}" SelectedItem="{Binding SelectItem}" AutoGenerateColumns="False" CanUserAddRows="False">
11 
12             <DataGrid.Columns>
13                 <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="*" />
14                 <DataGridTextColumn Header="年龄" Binding="{Binding Age}" Width="*" />
15                 <DataGridTextColumn Header="性别" Binding="{Binding Sex}" Width="*" />
16                 <DataGridTemplateColumn Header="电话" Width="*">
17                     <DataGridTemplateColumn.CellTemplate>
18                         <DataTemplate>
19                             <TextBox x:Name="TextBox_Phone" Text="{Binding Phone}">
20                                 <TextBox.InputBindings>
21                                     <KeyBinding Key="Return" Command="{Binding Path=DataContext.PressEnterKey, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}}" CommandParameter="{Binding ElementName=TextBox_Phone}"></KeyBinding>
22                                 </TextBox.InputBindings>
23                             </TextBox>
24                         </DataTemplate>
25                     </DataGridTemplateColumn.CellTemplate>
26                 </DataGridTemplateColumn>
27                 <DataGridTemplateColumn Header="删除" Width="*">
28                     <DataGridTemplateColumn.CellTemplate>
29                         <DataTemplate>
30                             <Button Content="删除" Command="{Binding Path=DataContext.DelClick, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}}" />
31                         </DataTemplate>
32                     </DataGridTemplateColumn.CellTemplate>
33                 </DataGridTemplateColumn>
34             </DataGrid.Columns>
35         </DataGrid>
36         <Button Margin="10,0,10,10" VerticalAlignment="Bottom" HorizontalAlignment="Left" Height="30" Width="100" Content="添加学生小刚" Command="{Binding AddClick}"></Button>
37         <TextBlock Margin="0,0,140,10" VerticalAlignment="Bottom" HorizontalAlignment="Right" Text="{Binding TextInfo}" FontSize="24"></TextBlock>
38         <Button Margin="0,0,10,10" VerticalAlignment="Bottom" HorizontalAlignment="Right" Height="30" Width="100" Content="修改Text内容" Command="{Binding ReviseClick}"></Button>
39     </Grid>
40 </Window>

MainWindow.xaml

MainWindow.xaml.cs

C# WPF数据绑定方法以及重写数据模板后数据绑定

 1 using System.Windows;
 2 
 3 namespace WpfExample
 4 {
 5     public partial class MainWindow : Window
 6     {
 7         public MainWindow()
 8         {
 9             InitializeComponent();
10             //绑定DataContext
11             DataContext = new MainWindowViewModel();
12         }
13     }
14 }

MainWindow.xaml.cs

实例效果:

 C# WPF数据绑定方法以及重写数据模板后数据绑定

主界面窗口,支持点击删除按钮删掉对应信息;支持修改姓名,年龄,性别,电话信息;支持修改电话信息按下回车键捕捉回车事件功能;支持点击左下角添加学生小刚按钮增加信息;支持点击右下角修改Text内容下方TextBlok控件内容变化。

 

C# WPF数据绑定方法以及重写数据模板后数据绑定

C# WPF数据绑定方法以及重写数据模板后数据绑定

点击删除按钮,弹出确认删除对话框,点击是则删除成功。

 

C# WPF数据绑定方法以及重写数据模板后数据绑定

C# WPF数据绑定方法以及重写数据模板后数据绑定

点击左下角“添加学生小刚”按钮,弹出是否确认添加小刚信息确认框,点击是则会添加小刚的信息。

 

C# WPF数据绑定方法以及重写数据模板后数据绑定

在电话信息中输入回车会显示点击了回车弹框,并且显示控件中的内容。

 

C# WPF数据绑定方法以及重写数据模板后数据绑定

点击右下角“修改Text内容按钮”下方TextBlock控件内容发生改变

 

C# WPF数据绑定方法以及重写数据模板后数据绑定

修改小明的姓名后点击删除按钮,提示信息显示小明的姓名也被更改,说明数据源同时进行了更改。

 


 

1.数据源:数据绑定是通过ViewModel作为数据源,绑定到前台xaml进行实现的。通过后台对于数据源的修改,可以将内容直接同步到前台界面上。可以详见上面数据的删除和添加以及修改Text的实例。People、SelectItem、TextInfo都是数据源。

2.命令:除了数据要进行实时更新以外,前台的操作也应该能够传输到后台,在后台逻辑做出响应。这时我们需要用到Command(命令),在本实例中展示了将按钮的点击事件和键盘的回车事件通过命令的方式传到后台,但命令的用法远不止这两种,可以在实际的开发过程中跟据不同的需求在进行学习和尝试。值得注意的是命令是可以带参数的,前台代码中的CommandParameter就是它的参数,例如按钮点击的命令可以通过参数来确定点击的是哪一个按钮,当然也可以给每一个按钮绑定一个独立的命令。DelClick、AddClick、ReviseClick、PressEnterKey都是命令。

3.数据模板的重写:在本实例中重写了DataGrid控件中的电话一列和删除一列的数据模板,我们可以看到电话一列重写为了TextBox删除一列重写为了Button,表头也可以进行数据模板的重写。在DataTemplate中你可以写几乎任意的控件,如果需要放多个控件可以使用Grid和StackPanel这类布局控件进行封装。值得注意的是当重写数据模板之后,对于命令绑定的写法需要格外注意,需要注意Path和RelativeSource属性,详见例子代码中的写法,如果按照常规Binding的写法你会发现后端无法收到你绑定的命令。

4.双向绑定:顾名思义绑定是双向的,不仅仅是后台数据更新后自动同步到前台,同时前台的数据更新也会自动同步到后台。这种双向绑定也是MVVM设计模式的一大特点,本实例中可以看到修改了小明的名字后,修改的内容在你没有进行任何操作的情况下自动同步到了后台的数据源中(值得注意的是这里需要让选中的cell失去焦点修改的内容才会同步到后台数据源),这就是双向绑定。当然在绑定的过程中你可以设置多种模式,如果不设置默认为双向绑定,设置的方法是通过Mode属性(Binding="{Binding Name ,Mode=TwoWay}")你可以设置Default、OneTime、OneWay、OneWayToSource、TwoWay。

 

以上就是本实例中涉及一些要点,这些内容是做WPF和C#开发的基本内容,希望他们能对你的学习和工作起到一些帮助,如果对于本文某些用法写法说法有任何的意见欢迎指正交流。谢谢。

 

2023.4.17下午两点五十五分

原文链接:https://www.cnblogs.com/hellohxs/archive/2023/04/17/15262161.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# WPF数据绑定方法以及重写数据模板后数据绑定 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • 总结C#删除字符串数组中空字符串的几种方法

    我来详细讲解一下”总结C#删除字符串数组中空字符串的几种方法”的完整攻略,具体步骤如下: 问题描述 在C#中,有时候我们需要删除字符串数组中的空字符串,以便得到有效的数据。那么我们就需要了解如何使用C#来删除字符串数组中的空字符串。 解决方案 本文将总结出几种实现字符串数组中删除空字符串的方法,并给出代码示例。 方法一:使用Linq的Where方法 我们可以…

    C# 2023年6月7日
    00
  • 在.NET程序崩溃时自动创建Dump的思路详解

    以下是关于在.NET程序崩溃时自动创建Dump的思路详解: 1. 问题描述 在.NET程序运行过程中,可能会遇到各问题,例如崩溃、死锁、内存泄漏等。为了更好地诊断和解决这些问题我们需要在程序崩溃时自创建Dump文件。本攻略将介绍如何实现在.NET程序崩溃时自动创建Dump文件。 2. 解决方案 在.NET程序中,我们使用Microsoft.Diagnosti…

    C# 2023年5月12日
    00
  • C#封装的Sqlite访问类实例

    下面是详细讲解“C#封装的Sqlite访问类实例”的完整攻略。 一、Sqlite简介 Sqlite是一个轻量级的关系型数据库管理系统,它的特点是轻巧、可嵌入、可移植和高效,在单机或低并发情况下是一个非常好的选择。在C#中,我们可以使用System.Data.Sqlite命名空间提供的Sqlite连接器来访问Sqlite数据库。 二、C#封装的Sqlite访问…

    C# 2023年5月31日
    00
  • 详解C#中多态性学习/虚方法/抽象方法和接口的用法

    详解C#中多态性学习 多态性 多态性是面向对象程序设计(OOP)的一个核心概念。在OOP中,多态性是指不同的类对相同的消息作出不同的响应。 多态性是OOP的三大基本特性之一,另外两个特性是封装和继承。它允许我们在一个类的层次结构中定义一个抽象类或接口,并让子类实现具体的行为。这种方法使代码更加灵活和可扩展。 虚方法 虚方法 (virtual method) …

    C# 2023年5月31日
    00
  • C#判断三角形的类型

    想要判断一个三角形的类型,我们需要知道它的三条边长。以下是判断三角形类型的完整攻略: 步骤一:获取三角形的边长 需要获取三角形三条边的长度,可以通过用户输入、数据库或者其他数据源来获得。在此示例中,我们假设有三个变量 a、b、c 分别存储三角形的三条边长。 步骤二:判断是否为三角形 要判断一个三角形的类型,首先需要确定它是否是三角形。三角形的判定规则是任意两…

    C# 2023年6月7日
    00
  • asp.net SharpZipLib的压缩与解压问题

    下面我将详细介绍关于“asp.net SharpZipLib的压缩与解压问题”的完整攻略。 什么是 SharpZipLib SharpZipLib 是 .NET 平台下使用的一个流行的压缩库,支持 Gzip、Deflate、BZip2 等多种压缩格式,并且它是在 zlib 许可证下发布的,因此免费且开源。 SharpZipLib 安装 在 Visual St…

    C# 2023年6月6日
    00
  • 获取asp.net服务器控件的客户端ID和Name的实现方法

    获取 ASP.NET 服务器控件的客户端 ID 和 name,可以采用多种方法。下面提供了两种常用的方法: 方法一:使用<%= %>标记 在 ASP.NET 中,可以使用 <%= %> 标记从服务端代码中注入JavaScript代码,从而获取服务器控件的客户端 ID 和 name。 例如,下面的示例演示了如何使用 <%= %&g…

    C# 2023年6月3日
    00
  • C#验证控件validator的简单使用

    下面是详细讲解“C#验证控件validator的简单使用”的完整攻略。 1. 什么是validator控件 validator控件是ASP.NET框架提供的一种用于客户端数据验证的控件。它可以帮助我们在客户端对用户提交的数据进行验证,有助于提高用户体验和数据的正确性。 2. validator控件的使用 2.1 基本使用 validator控件有多种类型,如…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部