WPF 开发从入门到进阶(五)

一、WPF 简介与开发环境搭建

1.1 WPF 概述

Windows Presentation Foundation(WPF)是微软推出的用于构建 Windows 桌面应用程序的强大 UI 框架。它融合了矢量图形、动画、多媒体等多种技术,能让开发者创建出具有高度视觉吸引力和交互性的应用界面。相较于传统的 Windows Forms,WPF 更注重界面的设计和用户体验,并且提供了更好的布局和样式控制能力。

1.2 开发环境搭建

1.2.1 安装 Visual Studio

访问微软官方网站下载并安装 Visual Studio。在安装过程中,选择 “.NET 桌面开发” 工作负载,其中包含了开发 WPF 应用所需的工具和框架。安装完成后,启动 Visual Studio。

1.2.2 创建 WPF 项目

打开 Visual Studio,选择 “创建新项目”。在搜索框中输入 “WPF 应用”,根据需求选择合适的项目模板,如 “WPF 应用(.NET 6.0)”,然后输入项目名称和存储位置,点击 “创建” 按钮。

二、XAML 基础与界面设计

2.1 XAML 基础语法

2.1.1 元素和属性

XAML 使用 XML 标签来定义界面元素,元素名称对应着.NET 类型。每个元素可以有多个属性,用于设置其外观和行为。例如:

<Button Content="Click Me" Width="120" Height="40" />

这里的 <Button> 是元素,ContentWidth 和 Height 是属性。

2.1.2 嵌套元素

元素可以嵌套,形成层次结构,用于构建复杂的界面布局。例如:

<StackPanel><TextBlock Text="Welcome to WPF!" FontSize="20" /><Button Content="Explore" Width="100" Height="30" />
</StackPanel>

<StackPanel> 是一个容器元素,包含了一个 <TextBlock> 和一个 <Button>

2.1.3 命名空间

XAML 文件需要定义命名空间来引用不同的类型。通常在根元素中定义默认命名空间和其他必要的命名空间。例如:

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Main Window" Height="450" Width="800"><!-- 窗口内容 -->
</Window>

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

2.2 常用布局容器

2.2.1 Grid

Grid 是一个强大的布局容器,它将界面划分为行和列的网格,子元素可以通过 Grid.Row 和 Grid.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>
2.2.2 StackPanel

StackPanel 按照水平或垂直方向排列子元素,通过 Orientation 属性设置排列方向,默认是垂直方向。例如:

<StackPanel Orientation="Horizontal"><Button Content="Button 1" /><Button Content="Button 2" /><Button Content="Button 3" />
</StackPanel>
2.2.3 WrapPanel

WrapPanel 子元素会按照指定的方向依次排列,当一行或一列排满时,会自动换行或换列。例如:

<WrapPanel><Button Content="Short Button" /><Button Content="A Longer Button" /><Button Content="Another Button" />
</WrapPanel>
2.2.4 DockPanel

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>

2.3 常用控件

2.3.1 Button

Button 是最常用的控件之一,用于触发操作。可以通过 Content 属性设置按钮显示的文本或其他内容,通过 Click 事件处理按钮的点击操作。例如:

<Button Content="Submit" Click="Button_Click" />

在代码隐藏文件中添加事件处理方法:

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

TextBox 用于用户输入文本。可以通过 Text 属性获取或设置文本内容,通过 TextChanged 事件响应文本的变化。例如:

<TextBox TextChanged="TextBox_TextChanged" />

在代码隐藏文件中添加事件处理方法:

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

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

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

在代码隐藏文件或 ViewModel 中设置数据源和属性:

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" };}
}
2.3.4 CheckBox

CheckBox 用于表示布尔值的选择状态。可以通过 IsChecked 属性获取或设置复选框的选中状态,通过 Checked 和 Unchecked 事件响应状态变化。例如:

<CheckBox Content="Remember Me" IsChecked="{Binding IsRememberMe}" />

在 ViewModel 中定义属性:

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

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 属性值与单选按钮的选中状态进行转换。

三、数据绑定与 MVVM 模式

3.1 数据绑定基础

3.1.1 绑定概念

数据绑定是 WPF 的核心特性之一,它建立了 UI 元素(绑定目标)和数据源(绑定源)之间的连接,使得 UI 元素能够自动反映数据源的变化,并且可以将用户在 UI 上的操作反馈到数据源。

3.1.2 绑定模式

  • OneWay:数据从绑定源流向绑定目标,当绑定源属性值发生变化时,绑定目标属性会自动更新,但绑定目标的变化不会影响绑定源。常用于显示只读数据的场景,如显示数据库中的记录。
<TextBlock Text="{Binding ReadOnlyProperty, Mode=OneWay}" />

  • TwoWay:数据在绑定源和绑定目标之间双向流动,当绑定源属性值变化时,绑定目标更新;当绑定目标属性值变化时,绑定源也会相应更新。常用于需要用户输入并更新数据的场景,如编辑表单。
<TextBox Text="{Binding EditableProperty, Mode=TwoWay}" />

  • OneTime:数据在初始化时从绑定源流向绑定目标,之后绑定源的变化不会再影响绑定目标。适用于数据在应用程序运行过程中不会改变的情况,如显示应用程序的版本号。
<TextBlock Text="{Binding AppVersion, Mode=OneTime}" />
3.1.3 实现数据绑定

  • 创建数据源:通常创建一个 ViewModel 类作为数据源。ViewModel 类应该实现 INotifyPropertyChanged 接口,以便在属性值发生变化时通知绑定目标更新。例如:
public class UserViewModel : INotifyPropertyChanged
{private string _name;public string Name{get { return _name; }set{_name = value;OnPropertyChanged(nameof(Name));}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

  • 设置 DataContext:在窗口或控件的代码隐藏文件中,将 ViewModel 的实例设置为 DataContext,这样 XAML 中的绑定就可以找到对应的数据源。
public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();UserViewModel viewModel = new UserViewModel();DataContext = viewModel;}
}

  • 在 XAML 中进行绑定:使用 Binding 标记扩展将 UI 元素的属性绑定到 ViewModel 的属性上。
<TextBox Text="{Binding Name}" />

3.2 MVVM 模式

3.2.1 MVVM 概述

MVVM(Model - View - ViewModel)是一种设计模式,用于分离 UI 设计和业务逻辑。它将视图(View)、视图模型(ViewModel)和模型(Model)分离,提高了代码的可维护性和可测试性。

  • Model:表示应用程序的数据和业务逻辑,如数据库实体、业务规则等。
  • View:负责界面的呈现,即 XAML 文件定义的 UI 元素。
  • ViewModel:作为 View 和 Model 之间的桥梁,负责处理视图的交互逻辑和数据转换,实现了视图和模型的解耦。
3.2.2 MVVM 示例

以下是一个简单的 MVVM 示例,实现一个用户信息显示和编辑的功能。

Model 类

public class User
{public string Name { get; set; }public int Age { get; set; }
}

ViewModel 类

public class UserViewModel : INotifyPropertyChanged
{private User _user;public User User{get { return _user; }set{_user = value;OnPropertyChanged(nameof(User));}}public UserViewModel(){User = new User { Name = "John Doe", Age = 30 };}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

View(XAML)

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="User Info" Height="300" Width="400"><Grid><StackPanel Margin="20"><TextBlock Text="Name:" /><TextBox Text="{Binding User.Name, Mode=TwoWay}" /><TextBlock Text="Age:" /><TextBox Text="{Binding User.Age, Mode=TwoWay}" /></StackPanel></Grid>
</Window>

代码隐藏文件(设置 DataContext)

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();UserViewModel viewModel = new UserViewModel();DataContext = viewModel;}
}

四、样式、模板与资源管理

4.1 样式基础

4.1.1 样式定义

样式是一种用于集中设置 UI 元素属性的机制,可以将一组属性应用到多个元素上,实现统一的外观风格。样式可以定义在资源字典中,也可以直接在 XAML 文件中定义。例如:

<Window.Resources><Style x:Key="MyButtonStyle" TargetType="Button"><Setter Property="Background" Value="LightBlue"/><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="16"/><Setter Property="Padding" Value="10"/></Style>
</Window.Resources>
<Button Style="{StaticResource MyButtonStyle}" Content="Styled Button"/>
4.1.2 样式继承

样式可以继承其他样式的属性,通过 BasedOn 属性来实现。例如:

<Window.Resources><Style x:Key="BaseButtonStyle" TargetType="Button"><Setter Property="Background" Value="LightGray"/><Setter Property="Foreground" Value="Black"/></Style><Style x:Key="DerivedButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="FontSize" Value="18"/></Style>
</Window.Resources>
<Button Style="{StaticResource DerivedButtonStyle}" Content="Inherited Styled Button"/>

4.2 模板基础

4.2.1 ControlTemplate

ControlTemplate 用于自定义控件的外观。它可以完全改变控件的可视化结构,而不仅仅是设置属性。例如,自定义一个按钮的模板:

<Window.Resources><ControlTemplate x:Key="CustomButtonTemplate" TargetType="Button"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"><ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="LightGray"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="border" Property="Background" Value="DarkGray"/></Trigger></ControlTemplate.Triggers></ControlTemplate>
</Window.Resources>
<Button Template="{StaticResource CustomButtonTemplate}" Content="Custom Button"/>
4.2.2 DataTemplate

DataTemplate 用于定义数据项的呈现方式。当我们将一个集合绑定到一个列表控件(如 ListViewComboBox 等)时,DataTemplate 可以决定每个数据项在界面上的显示形式。例如:

<Window.Resources><DataTemplate x:Key="PersonDataTemplate"><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}" Margin="5"/><TextBlock Text="{Binding Age}" Margin="5"/></StackPanel></DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding Persons}" ItemTemplate="{StaticResource PersonDataTemplate}"/>

4.3 资源字典

资源字典是一种用于集中管理样式、模板、画笔等资源的机制。可以将资源字典定义在单独的 .xaml 文件中,然后在多个 XAML 文件中引用。

4.3.1 创建资源字典文件

创建一个名为 MyResources.xaml 的文件,内容如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Style x:Key="SharedButtonStyle" TargetType="Button"><Setter Property="Background" Value="Orange"/><Setter Property="Foreground" Value="White"/></Style><DataTemplate x:Key="SharedDataTemplate"><TextBlock Text="{Binding SomeProperty}" Foreground="Red"/></DataTemplate>
</ResourceDictionary>
4.3.2 在 XAML 文件中引用资源字典
<Window.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="MyResources.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary>
</Window.Resources>
<Button Style="{StaticResource SharedButtonStyle}" Content="Shared Styled Button"/>
<ListBox ItemsSource="{Binding SomeCollection}" ItemTemplate="{StaticResource SharedDataTemplate}"/>

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

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

相关文章

DICOM医学影像数据访问控制与身份验证技术应用的重要性及其实现方法详解

DICOM医学影像数据访问控制与身份验证技术应用的重要性及其实现方法详解 在现代医疗体系中,DICOM(数字成像和通信医学标准)作为医学影像数据的核心标准,扮演着至关重要的角色。随着医疗信息化的深入发展,DICOM医学影像数据的安全性和隐私保护成为医疗机构亟需解决的关键问…

植物知识分享论坛毕设

1.这四个文件直接是什么关系&#xff1f;各自都是什么作用&#xff1f;他们之间是如何联系的&#xff1f; 关系与联系 UserController.java 负责接收外部请求&#xff0c;调用 UserService.java 里的方法来处理业务&#xff0c; 而 UserService.java 又会调用 UserMapper.jav…

Business processes A bridge to SAP and a guide to SAP TS410 certification

Business processes A bridge to SAP and a guide to SAP TS410 certification

算法 之 ST表

文章目录 区间最大值 ST表(Sparse Table)是一种高效处理静态数据区间查询的数据结构&#xff0c;主要的作用是用于快速查询区间的最值&#xff0c;区间GCD,区间按位与或 在这里以区间最大值为例子说明st表的模版 总体的思想就是定义dp[i][j]表示下标为i长度为2^j的区间的最大值…

Deepseek X 文心智能体:谐音梗广告创意大师

体验链接 飞书文档 一、引言 在当今竞争激烈的市场环境下&#xff0c;广告创意对于产品或服务的推广至关重要。谐音广告以其独特的语言魅力&#xff0c;能够迅速吸引受众的注意力并留下深刻印象。本智能体旨在利用 DeepSeek 模型强大的语言分析和推理能力&#xff0c;为用户…

libilibi项目优化(2)视频文件分块上传

第一版 文件分片上传过程总结 整个文件分片上传过程分为三个主要步骤&#xff1a;预上传、分片上传和获取已上传分块信息。以下是每个步骤的详细描述&#xff1a; 1. 预上传&#xff08;preUploadVideo&#xff09; 功能&#xff1a;生成唯一的上传 ID&#xff0c;并将文件…

TCP简单链接的编程实现

TCP简单链接的编程实现 本文主要介绍TCP应用层的编码实现。 TCP是一种面向连接的、可靠的、基于字节流的传输层协议&#xff0c;它是互联网协议套件&#xff08;TCP/IP&#xff09;中的核心协议之一&#xff0c;广泛应用于需要可靠数据传输的场景&#xff0c;如&#xff1a;网…

使用Multiprocessing模块创建子进程,需要放到__main__中

1 场景说明 在Python中&#xff0c;使用multiprocessing模块创建子进程时&#xff0c;将创建子进程的代码放在if __name__ __main__: 块之外&#xff0c;如下面代码&#xff1a; import multiprocessing import timedef test_func(name):print(f"子进程 {name} 开始运行…

描述<canvas>标签的主要用途,如何在其上绘制简单图形?

大白话描述标签的主要用途&#xff0c;如何在其上绘制简单图形&#xff1f; <canvas> 标签的主要用途 <canvas> 标签是 HTML5 中新增的一个标签&#xff0c;它就像是一块“画布”&#xff0c;你可以在网页上用它来绘制各种图形、动画、制作游戏等。简单来说&…

【RHCE实验】搭建主从DNS、WEB等服务器

目录 需求 环境搭建 配置nfs服务器 配置web服务器 配置主从dns服务器 主dns服务器 从dns服务器 配置客户端 客户端测试 需求 客户端通过访问 www.nihao.com 后&#xff0c;能够通过 dns 域名解析&#xff0c;访问到 nginx 服务中由 nfs 共享的首页文件&#xff0c;内容…

Shell条件判断

一、使用if选择结构 if单分支的语法组成&#xff1a; if 条件测试;then 命令序列 fi if双分支的语法组成&#xff1a; if 条件测试;then 命令序列1 else 命令序列2 fi if多分支的语法组成&#xff1a; if 条…

理解langchain langgraph 官方文档示例代码中的MemorySaver

以下是langchain v0.3官方示例代码 from langgraph.checkpoint.memory import MemorySaver from langgraph.graph import START, MessagesState, StateGraph# 可以理解为&#xff1a;定义一个流程&#xff0c;这个流程中用到的数据类型是Messages。 <---定义一个有向图&…

【HarmonyOS Next之旅】DevEco Studio使用指南(三)

目录 1 -> 一体化工程迁移 1.1 -> 自动迁移 1.2 -> 手动迁移 1.2.1 -> API 10及以上历史工程迁移 1.2.2 -> API 9历史工程迁移 1 -> 一体化工程迁移 DevEco Studio从 NEXT Developer Beta1版本开始&#xff0c;提供开箱即用的开发体验&#xff0c;将SD…

vuex持久化存储,手动保存到localStorage

vuex持久化存储&#xff0c;手动保存到localStorage 一、vue21. 手动存储到localStoragestore/index.js 2. 使用持久化存储插件store/index.jsstore/modules/otherData.js保存到localStorage 二、vue31. index.ts2. store/modules/globalData.ts3. 在组件中使用App.vue 一、vue…

nodejs使用 mysql2 模块获取 mysql 中的 json字段,而不是 mysql

mysql 模块获取的 json 字段&#xff0c;是字符串mysql2 模块获取的 json 字段&#xff0c;是符合预期的 json 对象 mysql mysql2 最后编辑于&#xff1a;2025-02-24 22:16:53 © 著作权归作者所有,转载或内容合作请联系作者 喜欢的朋友记得点赞、收藏、关注哦&#xff01;…

鸿蒙(OpenHarmony)开发实现 息屏/亮屏 详情

官网参考链接 实现点击关闭屏幕&#xff0c;定时5秒后唤醒屏幕 权限 {"name": "ohos.permission.POWER_OPTIMIZATION"}代码实现 import power from ohos.power;Entry Component struct Page3 {private timeoutID: number | null null; // 初始化 timeout…

【网工第6版】第1章 计算机网络概论

目录 1计算机网络形成和发展 ■计算机网络 ■我国互联网发展 ■计算机网路分类 ■计算机网络应用 2 OSI和TCP/IP参考模型 ■网络分层的意义 ■OSI参考模型 ■TCP/IP参考模型 ■TCP/IP参考模型协议 3 数据封装与解封过程 ■封装 ■解封 1计算机网络形成和发展 ■计…

理解我们单片机拥有的资源

目录 为什么要查询单片机拥有的资源 所以&#xff0c;去哪些地方可以找数据手册 一个例子&#xff1a;STM32F103C8T6 前言 本文章隶属于项目&#xff1a; Charliechen114514/BetterATK: This is a repo that helps rewrite STM32 Common Repositorieshttps://github.com/C…

《我的Python觉醒之路》之转型Python(十五)——控制流

[今天是2025年3月17日&#xff0c;继续复习第一章节、第二章节的内容 ] 《我的Python觉醒之路》之转型Python&#xff08;十四&#xff09;——控制流

AndroidStudio+Android8.0下的Launcher3 导入,编译,烧录,调试

文章目录 编译完成搜索输出文件Android.mk配置gradle编译环境报错一报错二报错三输出文件下载INSTALL_FAILED_TEST_ONLY查找系统签名查找签名工具开始签名查看签名签名问题重新生成秘钥解决方案生成成功挽救错误:重新刷机更换testkey秘钥keystore生成keystoreINSTALL_FAILED_S…