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

C# WPF 基础知识学习(一)

一、WPF 简介

Windows Presentation Foundation(WPF)是微软推出的一款用于构建用户界面的框架,它为开发 Windows 桌面应用程序提供了统一的编程模型、语言和框架。WPF 将用户界面的设计与业务逻辑分离开来,采用了 XAML(可扩展应用程序标记语言)来描述界面元素,使得界面设计更加直观和灵活。与传统的 Windows Forms 相比,WPF 在图形渲染、动画效果、数据绑定等方面具有显著优势,能够创建出更加美观、交互性强的应用程序。

(一)WPF 的特点

  1. 声明式 UI 设计:通过 XAML,开发人员可以以声明的方式描述用户界面的结构和外观,无需编写大量的代码来创建和管理界面元素。例如:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><Grid><Button Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid>
</Window>

这段 XAML 代码定义了一个包含一个按钮的窗口,按钮位于窗口的中心位置。

  1. 强大的图形渲染能力:WPF 基于 DirectX 技术,能够提供高质量的 2D 和 3D 图形渲染效果。它支持硬件加速,使得复杂的图形和动画能够流畅运行。通过使用 Path、Geometry 等元素,可以创建各种形状,并且可以对这些形状进行填充、描边等操作。例如:
<Path Stroke="Black" StrokeThickness="2"><Path.Data><EllipseGeometry Center="100,100" RadiusX="50" RadiusY="50"/></Path.Data>
</Path>

上述代码创建了一个黑色边框、半径为 50 的圆形。

  1. 丰富的动画支持:WPF 提供了一套完整的动画系统,包括线性动画、关键帧动画、路径动画等。可以通过动画来改变元素的属性,如位置、大小、透明度等,从而创建出生动的用户界面。例如,下面的代码实现了一个按钮在点击时逐渐变大的动画:
<Window.Resources><Storyboard x:Key="GrowButtonAnimation"><DoubleAnimation Storyboard.TargetProperty="Width"From="100" To="150" Duration="0:0:0.5"/><DoubleAnimation Storyboard.TargetProperty="Height"From="50" To="75" Duration="0:0:0.5"/></Storyboard>
</Window.Resources>
<Button Content="Animate Me" Click="Button_Click"><Button.Triggers><EventTrigger RoutedEvent="Button.Click"><BeginStoryboard Storyboard="{StaticResource GrowButtonAnimation}"/></EventTrigger></Button.Triggers>
</Button>

在后台代码中,Button_Click事件不需要额外的逻辑,因为动画已经通过 XAML 定义好了。

  1. 数据绑定:数据绑定是 WPF 的核心特性之一,它允许将 UI 元素与数据源进行关联,使得 UI 能够自动反映数据源的变化,并且数据源也能够根据 UI 的操作进行更新。数据绑定支持多种数据源,如对象、集合、XML 等。例如,将一个 TextBox 的 Text 属性绑定到一个 ViewModel 中的字符串属性:
<TextBox Text="{Binding MyProperty}"/>

在 ViewModel 中定义MyProperty属性:

public class ViewModel : INotifyPropertyChanged
{private string _myProperty;public string MyProperty{get { return _myProperty; }set{_myProperty = value;OnPropertyChanged(nameof(MyProperty));}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

这样,当MyProperty的值在 ViewModel 中发生变化时,TextBox 中的文本会自动更新。

  1. 样式和模板:WPF 允许通过样式和模板来定义 UI 元素的外观和行为。样式可以集中设置一组属性,应用到多个元素上,实现统一的外观风格。模板则可以自定义元素的可视化结构,例如为 Button 创建自定义的模板,使其具有独特的外观。
<Style x:Key="MyButtonStyle" TargetType="Button"><Setter Property="Background" Value="LightBlue"/><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="14"/>
</Style>
<Button Style="{StaticResource MyButtonStyle}" Content="Styled Button"/>

通过定义MyButtonStyle样式,并将其应用到 Button 上,按钮就具有了浅蓝色背景、白色前景色和 14 号字体的样式。

(二)WPF 的应用场景

  1. 桌面应用程序开发:无论是企业级的业务应用程序,还是面向消费者的工具软件,WPF 都能够提供良好的用户体验。例如,办公软件、图形设计工具、数据分析应用等。
  2. 多媒体应用:由于其强大的图形渲染和动画能力,WPF 适用于开发视频播放器、音频编辑软件、游戏界面等多媒体相关的应用。
  3. 数据可视化应用:在需要展示大量数据的场景中,如金融数据可视化、科学数据展示等,WPF 的数据绑定和丰富的图形元素能够方便地创建直观的数据可视化界面。

二、创建 WPF 项目

(一)安装开发环境

要开发 WPF 应用程序,首先需要安装 Visual Studio。可以从微软官方网站下载并安装最新版本的 Visual Studio,在安装过程中,确保选择了 “.NET 桌面开发” 工作负载,其中包含了开发 WPF 应用所需的工具和框架。

(二)创建项目

  1. 打开 Visual Studio,选择 “创建新项目”。
  2. 在项目模板列表中,选择 “WPF 应用 (.NET Framework)”(如果使用的是.NET Core 或.NET 5 及以上版本,可选择对应的 WPF 项目模板)。
  3. 输入项目名称和存储位置,点击 “创建” 按钮。

(三)项目结构

创建完成后,项目中会包含以下主要文件和文件夹:

  1. App.xaml:应用程序的入口点,包含应用程序的资源、启动设置等。在 App.xaml.cs 文件中,可以编写应用程序的启动逻辑。
public partial class App : Application
{protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);MainWindow mainWindow = new MainWindow();mainWindow.Show();}
}

  1. MainWindow.xaml:主窗口的 XAML 文件,用于定义主窗口的界面布局和元素。对应的 MainWindow.xaml.cs 文件包含窗口的代码逻辑,如事件处理程序等。
  2. Properties 文件夹:包含项目的属性设置,如应用程序图标、版本信息等。
  3. References 文件夹:列出了项目所引用的程序集,通过添加引用可以使用其他库中的功能。

三、XAML 基础

(一)XAML 语法

  1. 元素和属性:XAML 中的元素对应于.NET 类型,元素名称通常与类型名称相同。属性用于设置元素的特性,例如:
<Button Content="OK" Width="100" Height="30" Background="Green"/>

这里Button是元素,ContentWidthHeightBackground是属性。属性值可以是简单的文本、数值,也可以是更复杂的对象,如颜色对象(通过颜色名称或 RGB 值表示)。

  1. 嵌套元素:元素可以嵌套在其他元素内部,形成层次结构。例如:
<StackPanel><TextBlock Text="First Line"/><TextBlock Text="Second Line"/>
</StackPanel>

StackPanel是一个容器元素,它包含了两个TextBlock元素,StackPanel会按照垂直方向依次排列这些子元素。

  1. 命名空间:XAML 使用命名空间来引用不同的类型。在每个 XAML 文件的根元素中,通常会定义默认命名空间和其他需要的命名空间。例如:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><!-- 窗口内容 -->
</Window>

默认命名空间http://schemas.microsoft.com/winfx/2006/xaml/presentation包含了 WPF 的核心 UI 元素类型,如WindowButtonGrid等。xmlns:x引用的命名空间用于 XAML 语言本身的特性,如x:Class用于指定代码隐藏文件中对应的类。

  1. XAML 语法扩展:XAML 提供了语法扩展机制,用于创建更复杂的属性值。常见的语法扩展有BindingStaticResourceDynamicResource等。例如,Binding扩展用于数据绑定:
<TextBox Text="{Binding MyProperty}"/>

StaticResource扩展用于引用资源字典中的资源:

<Button Style="{StaticResource MyButtonStyle}"/>

(二)常用 XAML 元素

  1. 布局容器
    • Grid:是最常用的布局容器之一,它将界面划分为行和列的网格,子元素可以通过Grid.RowGrid.Column附加属性指定在网格中的位置。例如:
<Grid><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Button Content="Top - Left" Grid.Row="0" Grid.Column="0"/><Button Content="Top - Right" Grid.Row="0" Grid.Column="1"/><Button Content="Bottom - Left" Grid.Row="1" Grid.Column="0"/><Button Content="Bottom - Right" Grid.Row="1" Grid.Column="1"/>
</Grid>

  • StackPanel:按照水平或垂直方向排列子元素。通过Orientation属性可以设置排列方向,默认是垂直方向。例如:
<StackPanel Orientation="Horizontal"><Button Content="Button 1"/><Button Content="Button 2"/><Button Content="Button 3"/>
</StackPanel>

  • WrapPanel:子元素会按照指定的方向依次排列,当一行或一列排满时,会自动换行或换列。例如:
<WrapPanel><Button Content="Short Button"/><Button Content="A Longer Button"/><Button Content="Another Button"/>
</WrapPanel>

  • DockPanel:子元素可以停靠在面板的边缘,通过DockPanel.Dock附加属性设置停靠位置。例如:
<DockPanel><Button Content="Top" DockPanel.Dock="Top"/><Button Content="Bottom" DockPanel.Dock="Bottom"/><Button Content="Left" DockPanel.Dock="Left"/><Button Content="Right" DockPanel.Dock="Right"/><Button Content="Center"/>
</DockPanel>

  1. 控件元素
    • Button:按钮控件,用于触发操作。可以通过Content属性设置按钮显示的文本或其他内容(如图片),通过Click事件处理按钮的点击操作。
<Button Content="Submit" Click="Button_Click"/>

在后台代码中:

private void Button_Click(object sender, RoutedEventArgs e)
{MessageBox.Show("Button clicked!");
}

  • TextBox:用于输入文本。可以通过Text属性获取或设置文本内容,通过TextChanged事件响应文本的变化。
<TextBox TextChanged="TextBox_TextChanged"/>

后台代码:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{TextBox textBox = (TextBox)sender;string text = textBox.Text;// 处理文本变化逻辑
}

  • ComboBox:下拉列表框,用户可以从预定义的选项中选择一个值。通过ItemsSource属性绑定数据源,通过SelectedItemSelectedValue属性获取当前选中的项。

<ComboBox ItemsSource="{Binding MyItems}" SelectedValue="{Binding SelectedItem}"/>

假设在 ViewModel 中定义了MyItems集合和SelectedItem属性:

public class ViewModel
{public ObservableCollection<string> MyItems { get; set; }public string SelectedItem { get; set; }public ViewModel(){MyItems = new ObservableCollection<string>() { "Option 1", "Option 2", "Option 3" };}
}

  • CheckBox:复选框控件,用于表示布尔值的选择状态。通过IsChecked属性获取或设置复选框的选中状态,通过CheckedUnchecked事件响应状态变化。
<CheckBox Content="Remember Me" IsChecked="{Binding IsRememberMe}"/>

在 ViewModel 中定义IsRememberMe属性:

private bool _isRememberMe;
public bool IsRememberMe
{get { return _isRememberMe; }set{_isRememberMe = value;OnPropertyChanged(nameof(IsRememberMe));}
}

  • RadioButton:单选按钮,一组单选按钮中只能有一个被选中。通过GroupName属性将多个单选按钮分组,通过IsChecked属性判断是否被选中。
<StackPanel><RadioButton Content="Male" GroupName="Gender" IsChecked="{Binding Gender, Converter={StaticResource GenderConverter}, ConverterParameter=Male}"/><RadioButton Content="Female" GroupName="Gender" IsChecked="{Binding Gender, Converter={StaticResource GenderConverter}, ConverterParameter=Female}"/>
</StackPanel>

这里使用了一个转换器GenderConverter来将 ViewModel 中的Gender属性值与单选按钮的选中状态进行转换。

相关文章:

C# WPF 基础知识学习(一)

一、WPF 简介 Windows Presentation Foundation&#xff08;WPF&#xff09;是微软推出的一款用于构建用户界面的框架&#xff0c;它为开发 Windows 桌面应用程序提供了统一的编程模型、语言和框架。WPF 将用户界面的设计与业务逻辑分离开来&#xff0c;采用了 XAML&#xff0…...

MATLAB基于ResNet18的交通标志识别系统

1. 数据准备 数据集&#xff1a;该数据集包含了大量标注好的交通标志图片&#xff0c;每类标志都有不同的样本。数据预处理&#xff1a;图像需要进行一些基本的预处理&#xff0c;如调整大小、归一化等&#xff0c;以适应ResNet18的输入要求。 2. 网络设计 使用MATLAB自带的…...

CSS3-流星雨

1. 绘制标签 <div class"container"><span></span> </div>2. 设置div背景 在百度上搜索一幅星空的图片 <style>* {/* 初始化 */margin: 0;padding: 0;}body {/* 高度100% */height: 100vh;/* 溢出隐藏 */overflow: hidden;}.contai…...

数学建模 第一节

目录​​​​​​ 前言 一 优化模型的类型 二 线性规划1 线性规划2 三 0-1规划 总结 前言 数学建模主要是将问题转化为模型&#xff0c;然后再以编程的形式输出出来 算法都知道&#xff0c;数学建模也需要用到算法&#xff0c;但是不是主要以编程形式展示&#xff0c;而是…...

平方矩阵问题

Ⅰ 回字形二维数组 #include <iostream> #include <iomanip> using namespace std; int main(){int n;while(cin>>n,n){for(int i0; i<n;i){for(int j0; j<n; j){int upi, downn-i1, leftj, rightn-j1;cout<<min(min(up,down),min(left,right)…...

自动化立体仓库堆垛机HMI屏幕程序施耐德HMIGXU系列 Vijeo Designer功能设计

堆垛机HMI屏幕功能概况 在自动化立体仓库堆垛机的HMI屏幕程序里,有着施耐德HMIGXU系列Vijeo Designer功能设计。此HMI程序运用标准的工程组织结构,凭借拖拽方式迅速构建人机交互界面。 其主要功能涵盖:设备参数、设备状态、手动/自动操作控制、报警显示、IO信息监控等模块…...

孤儿进程与僵尸进程:Linux进程管理中的“隐形杀手”与“无主孤儿”

在Linux系统中&#xff0c;进程的生命周期管理是系统稳定运行的关键。其中&#xff0c;​孤儿进程和僵尸进程是两种特殊状态&#xff0c;它们看似相似却暗藏玄门。本文将从定义、区别到处理方法&#xff0c;揭开它们的神秘面纱。 一、孤儿进程&#xff1a;被“遗弃”的孩子&…...

信息系统运行管理员教程6--信息系统安全

信息系统运行管理员教程6–信息系统安全 第1节 信息系统安全概述 1.信息系统安全的概念 信息系统安全是指保障计算机及其相关设备、设施&#xff08;含网络&#xff09;的安全&#xff0c;运行环境的安全&#xff0c;信息的安全&#xff0c;实现信息系统的正常运行。信息系统…...

实验- 分片上传 VS 直接上传

分片上传和直接上传是两种常见的文件上传方式。分片上传将文件分成多个小块&#xff0c;每次上传一个小块&#xff0c;可以并行处理多个分片&#xff0c;适用于大文件上传&#xff0c;减少了单个请求的大小&#xff0c;能有效避免因网络波动或上传中断导致的失败&#xff0c;并…...

训练数据重复采样,让正负样本比例1:1

详细解释 resample 函数&#xff1a; resample 函数来自 sklearn.utils&#xff0c;用于从数据集中重新抽样。replaceTrue 表示允许重复抽样&#xff0c;即同一个样本可以被多次选中。n_samples 指定抽样的数量。 确保训练集数量相同&#xff1a; 通过 resample 函数&#xff…...

生活中的可靠性小案例12:类肤材质老化发粘问题

我一直觉得我买的某品牌车载吸尘器很好用&#xff0c;用了几年&#xff0c;目前性能也是杠杠的。然而它现在有个最大的问题&#xff0c;就是表面发粘了&#xff0c;用起来粘手&#xff0c;非常不舒服。 这一类问题在生活中不少见&#xff0c;尤其是一些用了类肤材质涂层的物件。…...

qt 自带虚拟键盘的编译使用记录

一、windows 下编译 使用vs 命令窗口&#xff0c;分别执行&#xff1a; qmake CONFIG"lang-en_GB lang-zh_CN" nmake nmake install 如果事先没有 指定需要使用的输入法语言就进行过编译&#xff0c;则需要先 执行 nmake distclean 清理后执行 qmake 才能生效。 …...

python中print函数的flush如何使用

在 Python 中&#xff0c;print 函数的 flush 参数是一个布尔值&#xff0c;默认值为 False。当设置为 True 时&#xff0c;它会强制将输出缓冲区的内容立即刷新到目标设备&#xff08;通常是控制台&#xff09;&#xff0c;而不是等待缓冲区满或者程序结束时才输出。 要注意fl…...

k8s集群-kubeadm init

为了使用阿里云的镜像源加速 kubeadm init 初始化 Kubernetes 集群的过程&#xff0c;你需要修改 kubeadm 的配置文件以指向阿里云提供的镜像仓库。以下是具体步骤&#xff1a; 1. 创建或编辑 kubeadm 配置文件 首先&#xff0c;创建一个 kubeadm 的配置文件&#xff08;如果还…...

【软考-架构】5.2、传输介质-通信方式-IP地址-子网划分

✨资料&文章更新✨ GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目录 传输介质网线光纤无线信道 通信方式和交换方式会考&#xff1a;交换方式 &#x1f4af;考试真题第一题第二题 IP地址表示子网划分&#x1f4af;考试真题第一题第二题 传输…...

记一次OOM异常问题排查

背景 最近&#xff0c;有运维同事收到告警&#xff0c;提示服务器出现CPU占用100%的情况出现&#xff0c;并且严重影响服务性能&#xff0c;甚至导致一些功能不可用。接到上述情况反馈后&#xff0c;随即展开对问题的排查。 排查 CPU占用100%排查 定位进程&#xff1a;使用 t…...

websocket学习手册及python实现简单的聊天室

概述 WebSocket 是一种网络通信协议&#xff0c;允许在单个 TCP 连接上进行全双工通信。它最核心的优势就在于实现了持久连接&#xff0c;实现了实时的数据传输。HTTP 协议有一个很大的缺点&#xff0c;通信只能由客户端发起&#xff0c;服务器返回响应后连接就会关闭&#xf…...

SpringMVC (二)请求处理

目录 章节简介 一 请求处理&#xff08;初级&#xff09; eg:请求头 二 请求处理&#xff08;进阶&#xff09; eg:请求体 三 获取请求头 四 获取Cookie 五 级联封装 六 使用RequestBoby封装JSON对象 七 文件的上传 八 获取整个请求 HttpEntity 九 原生请求 Spring…...

Android (Kotlin) 高版本 DownloadManager 封装工具类,支持 APK 断点续传与自动安装

以下是一个针对 Android 高版本的 DownloadManager 封装工具类&#xff0c;支持 断点续传 和 自动安装 APK 功能。该工具类兼容 Android 10 及以上版本的文件存储策略&#xff0c;并适配了 FileProvider 和未知来源应用安装权限。 工具类&#xff1a;DownloadUtils import and…...

深入探索Android Bitmap:从原理到实战

一、Bitmap 是什么 在 Android 开发中,Bitmap 是极为重要的基石。简单来说,Bitmap 代表位图,是图片在内存里的具体呈现形式 ,任何诸如 JPEG、PNG、WEBP 等格式的图片,一旦被加载到内存中,就会以 Bitmap 对象的形式存在。从原理上看,Bitmap 本质是像素点的集合,若其宽度…...

​详细介绍 SetWindowPos() 函数

书籍&#xff1a;《Visual C 2017从入门到精通》的2.3.8 Win32控件编程 环境&#xff1a;visual studio 2022 内容&#xff1a;【例2.29】模态对话框 说明&#xff1a;以下内容大部分来自腾讯元宝。 ​1. 函数功能与用途 SetWindowPos() 是 Windows API 中用于动态调整窗口…...

1.6、Java继承、构造方法、数组

子类可以增加字段、增加方法或覆盖父类方法&#xff0c;但继承不会删除任何字段和方法不恰当认为super 同 this 引用是类似的概念&#xff0c;其实super不是一个对象的引用&#xff0c;不能将值super赋给另一个对象变量&#xff0c;super只是一个指示 编译器调用父类方法的特殊…...

通义万相 2.1 与蓝耘智算平台的深度协同,挖掘 AIGC 无限潜力并释放巨大未来价值

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 引言&#xff1a;AIGC 浪潮下的新机遇 在当今数字化飞速发展的时代&#xff0c;人工智能生成内容&…...

Spring Boot项目中成功集成了JWT

JWT 原理解释 什么是 JWT&#xff1f; JSON Web Token&#xff08;JWT&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用环境间安全地将信息作为JSON对象传输。JWT通常用于身份验证和信息交换。 JWT 的结构 JWT由三部分组成&#xff…...

DeepSeek 3FS集群化部署临时笔记

DeepSeek 3FS集群化部署临时笔记 一、3FS集群化部署1、环境介绍2、对应的软件包安装3、编译4、部署4.1 部署monitor_collector_mainStep 2: Admin clientStep 3: Mgmtd serviceStep 4: Meta serviceStep 5: Storage serviceStep 6: Create admin user, storage targets and cha…...

专题|Python贝叶斯金融数据应用实例合集:随机波动率SV模型、逻辑回归、参数更新、绩效比较BEST分析亚马逊股票、普尔指数...

原文链接&#xff1a;https://tecdat.cn/?p41020 本专题合集系统梳理了贝叶斯方法在金融数据分析与分类建模中的前沿应用。合集聚焦于PyMC3概率编程框架&#xff0c;深度探讨了共轭先验参数更新、贝叶斯逻辑回归、贝叶斯夏普比率等核心算法在实际场景中的落地实践&#xff08;…...

RocketMQ企业应用篇

在现代企业级应用中&#xff0c;分布式消息队列系统如RocketMQ发挥着至关重要的作用。本文将深入探讨RocketMQ在电商和物联网场景中的应用&#xff0c;结合实际案例和代码示例&#xff0c;展示如何利用RocketMQ解决企业级应用中的关键问题。 一、电商场景应用 1. 秒杀抢购解决…...

vue-常用指令 | 常用指令的修饰符

目录 什么是vue指令 v-cloak v-text v-html v-pre v-show /v-if v-else/v-else-if v-on v-bind v-for v-model 常用指令的修饰符 v-model 指令修饰符 事件修饰符 按键修饰符 什么是vue指令 指令就是带有 v- 前缀 的特殊 属性&#xff0c;不同的属性对应不…...

Git提交前时间检查

为了防止在本地看日志的时候&#xff0c;由于本地时间被修改&#xff0c;导致日志的时间存在非正确时间。通过以下脚本在提交前进行时间验证&#xff0c;只有是正确的时间才可以提交。 使用方法如下&#xff1a; 复制如下脚本&#xff0c;命名为 pre-commit &#xff0c;放到 …...

Linux调度器 --- 负载均衡的存在的问题

文章目录 前言一、简介二、Linux 调度器2.1 在单核系统上&#xff0c;CFS 非常简单2.2 在多核系统上&#xff0c;CFS 变得非常复杂2.2.1 负载均衡算法2.2.2 优化措施 三、Linux调度器负载均衡的存在的问题3.1 组负载不均衡问题&#xff08;Group Imbalance Bug&#xff09;3.2 …...