当前位置: 首页 > news >正文

WPF基础内容记录

目录

简介

一、样式基础

二、控件模板

三、数据模板

四、WPF绑定相关

1.绑定

2. 命令(ICommand)

3. 通知更改


简介

Windows Presentation Foundation (WPF) 是 Microsoft 提供的一个图形子系统,用于开发具有丰富用户界面的桌面应用程序。它通过提供强大的功能和灵活的设计,成为了开发 Windows 应用程序的首选框架之一。WPF 支持高度可定制化的 UI 设计,功能包括但不限于数据绑定、样式、控件模板、命令以及通知更改等,这些都帮助开发者轻松实现灵活而美观的用户界面。

在这篇文章中,我们将深入探讨一些 WPF 的基础概念,帮助初学者了解如何使用这些功能来构建应用程序。我们将涵盖以下几个重要的方面:

  1. 基础样式 (Styles):如何使用样式统一控件的外观。
  2. 控件模板 (Control Templates):如何自定义控件的结构和外观。
  3. 数据模板 (Data Templates):如何控制数据的展示方式。
  4. 控件绑定 (Data Binding):如何绑定控件的属性与数据源,保持 UI 与数据的同步。
  5. 命令 (Commands):如何使用命令模式来处理用户的操作。
  6. 通知更改 (INotifyPropertyChanged):如何通知 UI 属性发生了变化,进行实时更新。

一、样式基础

目的:给某些具有相同样式的控件,设置一个可以统一使用的样式。

1. 一个WPF的页面在普通设计实现的过程是:

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Grid><StackPanel><Button Content="button1"FontSize="18"Foreground="White"Background="Blue"></Button><Button Content="button2"FontSize="18"Foreground="White"Background="Blue"></Button><Button Content="button3"FontSize="18"Foreground="White"Background="Blue"></Button></StackPanel></Grid>
</Window>

2. 这三个按钮除了内容不同,其他属性都是相同的,那么就可以设计一个统一的样式,使得这三个按钮只需要应用同一个样式,而不需要针对于单个按钮进行设计。

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Window.Resources><Style TargetType="Button"><Setter Property="FontSize"Value="18" /><Setter Property="Foreground"Value="White" /><Setter Property="Background"Value="Blue" /><Setter Property="Content"Value="Button1" /></Style></Window.Resources><Grid><StackPanel><Button></Button><Button></Button><Button></Button></StackPanel></Grid>
</Window>

3. 可以看到,在Button的属性列表中,并没有设计样式,但是页面上,样式已经显示出来了。因为没有给这个样式设置固定的名称,默认作用域是全局的。

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Window.Resources><Style x:Key="ButtonStyle" TargetType="Button"><Setter Property="FontSize"Value="18" /><Setter Property="Foreground"Value="White" /><Setter Property="Background"Value="Blue" /><Setter Property="Content"Value="Button1" /></Style></Window.Resources><Grid><StackPanel><Button Style="{StaticResource ButtonStyle}"></Button><Button Style="{StaticResource ButtonStyle}"></Button><Button Style="{StaticResource ButtonStyle}"></Button></StackPanel></Grid>
</Window>

4. 同样,样式集也可以有继承关系,BaseON。

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Window.Resources><Style x:Key="BaseButtonStyle"TargetType="Button"><Setter Property="FontSize"Value="18" /><Setter Property="Foreground"Value="White" /><Setter Property="Background"Value="Blue" /></Style><Style x:Key="ButtonStyle"TargetType="Button"BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Content"Value="Button1" /></Style></Window.Resources><Grid><StackPanel><Button Content="button1"Style="{StaticResource ButtonStyle}"></Button><Button Content="button2"Style="{StaticResource ButtonStyle}"></Button><Button Content="button3"Style="{StaticResource ButtonStyle}"></Button></StackPanel></Grid>
</Window>

元素的属性值优先级是最高的,无论在样式表中如何设计,在元素的属性中设置值之后,元素的属性值优先显示.

二、控件模板

文本大纲==》选择Button并右键==》编辑模板==》编辑副本==》确定

Button中能显示很多内容的主要原因是有ContentPresenter

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Window.Resources><Style x:Key="FocusVisual"><Setter Property="Control.Template"><Setter.Value><ControlTemplate><Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/></ControlTemplate></Setter.Value></Setter></Style><SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/><SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/><SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/><SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/><SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/><SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/><SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/><SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/><SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/><Style x:Key="ButtonStyle1" TargetType="{x:Type Button}"><Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/><Setter Property="Background" Value="{StaticResource Button.Static.Background}"/><Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/><Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/><Setter Property="BorderThickness" Value="1"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Padding" Value="1"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"><ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border><ControlTemplate.Triggers><Trigger Property="IsDefaulted" Value="true"><Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/></Trigger><Trigger Property="IsMouseOver" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/></Trigger><Trigger Property="IsPressed" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/><Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></Window.Resources><Grid><StackPanel><Button Style="{DynamicResource ButtonStyle1}"><StackPanel Orientation="Horizontal"><Button Content="1"></Button><Button Content="2"></Button><Button Content="3"></Button><Button Content="4"></Button></StackPanel></Button></StackPanel></Grid>
</Window>

三、数据模板

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Grid><DataGrid Name="list"AutoGenerateColumns="False"CanUserAddRows="False"><DataGrid.Columns><DataGridTextColumn Binding="{Binding Code}"Header="Code" /><DataGridTextColumn Binding="{Binding Name}"Header="Name" /><DataGridTemplateColumn Header="操作"><DataGridTemplateColumn.CellTemplate><DataTemplate><!--<StackPanel Orientation="Horizontal"><Button Content="删除" /><Button Content="复制" /><Button Content="保存" /></StackPanel>--><StackPanel Orientation="Horizontal"><Border Width="10"Height="10"Background="{Binding Code}" /><TextBlock Margin="10,0"Text="{Binding Name}" /></StackPanel></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn></DataGrid.Columns></DataGrid></Grid>
</Window>
using System.Windows;namespace Style_base
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();List<Color> test = new List<Color>();test.Add(new Color() { Code = "#FFB6C1", Name = "浅粉红" });test.Add(new Color() { Code = "#FFC0CB", Name = "粉红" });test.Add(new Color() { Code = "#DC143C", Name = "深红(猩红)" });test.Add(new Color() { Code = "#FFF0F5", Name = "淡紫红" });list.ItemsSource = test;}}public class Color{public string Code { get; set; }public string Name { get; set; }}
}

四、WPF绑定相关

1.绑定

绑定控件上的值以及绑定属性值.

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Grid><StackPanel><Slider Name="slider"Margin="5" /><TextBox Text="{Binding ElementName=slider,Path=Value,Mode=Default}"Margin="5" /><TextBox Text="{Binding ElementName=slider,Path=Value,Mode=OneTime}"Margin="5" /><TextBox Text="{Binding ElementName=slider,Path=Value,Mode=OneWay}"Margin="5" /><TextBox Text="{Binding ElementName=slider,Path=Value,Mode=OneWayToSource}"Margin="5" /><TextBox Text="{Binding ElementName=slider,Path=Value,Mode=TwoWay}"Margin="5" /><TextBox Text="{Binding Name}"Height="30"Margin="5" /></StackPanel></Grid>
</Window>
using System.Reflection.Metadata.Ecma335;
using System.Windows;namespace Style_base
{public partial class MainWindow : Window{        public MainWindow(){InitializeComponent();DataContext = new Test() { Name = "张三" };}}public class Test{public string Name { get; set; }}
}

2. 命令(ICommand)

<Window x:Class="Style_base.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Style_base"mc:Ignorable="d"Title="MainWindow" Height="450"Width="800"><Grid><Button Content="Click_Me" Height="46" Width="120" Command="{Binding ShowCommand}" /></Grid>
</Window>
using System.Reflection.Metadata.Ecma335;
using System.Windows;namespace Style_base
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();DataContext = new MainViewModel();}}
}

 继承ICommand类,实现自己的Command类。

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace Style_base
{public class MyCommand : ICommand{Action executeAction;public MyCommand(Action action){executeAction = action;}public event EventHandler? CanExecuteChanged;public bool CanExecute(object? parameter){return true;}public void Execute(object? parameter){executeAction();}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace Style_base
{public class MainViewModel{public MainViewModel(){ShowCommand = new MyCommand(Show);}public MyCommand ShowCommand { get; set; }public void Show(){MessageBox.Show("点击按钮命令执行成功");}}
}

3. 通知更改

在2的MainViewModel中简单修改

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace Style_base
{public class MainViewModel : INotifyPropertyChanged{public MainViewModel(){Name = "Hello WPF!";ShowCommand = new MyCommand(Show);}public MyCommand ShowCommand { get; set; }private string name;public string Name {get { return name; } set { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); } }public event PropertyChangedEventHandler? PropertyChanged;public void Show(){Name = "点击按钮命令执行成功";MessageBox.Show(Name);}}
}

即可实现

封装成方法

新建一个基类View ModelBase

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace Style_base
{public class ViewModelBase : INotifyPropertyChanged{public event PropertyChangedEventHandler? PropertyChanged;public void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

在MainViewModel中使用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace Style_base
{public class MainViewModel : ViewModelBase{public MainViewModel(){Name = "Hello WPF!";ShowCommand = new MyCommand(Show);}public MyCommand ShowCommand { get; set; }private string name;public string Name {get { return name; } set { name = value; OnPropertyChanged("Name"); } }public void Show(){Name = "点击按钮命令执行成功";MessageBox.Show(Name);}}
}

让方法自动识别是哪个属性发生了改变

对ViewModelBase进行改变

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace Style_base
{public class ViewModelBase : INotifyPropertyChanged{public event PropertyChangedEventHandler? PropertyChanged;public void OnPropertyChanged([CallerMemberName]string propertyName =""){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

在MainViewModel中使用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace Style_base
{public class MainViewModel : ViewModelBase{public MainViewModel(){Name = "Hello WPF!";ShowCommand = new MyCommand(Show);}public MyCommand ShowCommand { get; set; }private string name;public string Name {get { return name; } set { name = value; OnPropertyChanged(); } }public void Show(){Name = "点击按钮命令执行成功";MessageBox.Show(Name);}}
}

http://www.dtcms.com/a/297005.html

相关文章:

  • RPG65. 制作死亡画面(一):制作ui
  • OSPF路由协议(单区域)
  • 解决 SQL 错误 [1055]:深入理解 only_full_group_by 模式下的查询规范
  • ddos 放在多个云主机,同时运行
  • 计算机网络知识点总结 (1)
  • Web前端:JavaScript indexOf()方法
  • 腾势N9再进化:智能加buff,豪华更对味
  • 无线通信资源分配相关算法
  • ESP32-S3学习笔记<6>:ADC的应用
  • AI助力 三步实现电子发票发票号码的提取
  • 小架构step系列24:功能模块
  • 【ResizeObserver】【页面布局】监听一个 div 元素的动态高度变化并同步设置另一个元素的高度
  • Windows环境下 Go项目迁移至Ubuntu(WSL) 以部署filebeat为例
  • 【数组的定义与使用】
  • 保障工业核心命脉:深度解读工业交换机QoS的“智能流量治理”之道
  • CMake ARGV变量使用指南
  • Python桌面版数独(五版)-优化选择模式触发新棋盘生成
  • OSPF 实验
  • RuoYi-Vue 项目 Docker 全流程部署实战教程
  • 中国、美国、欧盟、日本、英国临床试验API数据接口
  • Ⅹ—6.计算机二级综合题7---10套
  • Mac系统机能连接操控别的平台设备吗?能被远程操作吗?
  • Nginx快速入门及案例
  • 【安卓笔记】解决livedata粘性事件
  • 《Java语言程序设计》第2章复习题(2)
  • RePlugin 坑位使用原理与指南
  • 多源信息融合智能投资【“图神经网络+强化学习“的融合架构】【低配显卡正常运行】
  • 模拟退火算法 (Simulated Annealing, SA)简介
  • JavaWeb学习打卡14(JSP内置对象及作用域)
  • ARM汇编常见伪指令及其用法示例