编辑
2025-10-06
C#
00

在C#中,Control类是Windows Forms应用程序中所有控件的基类。它提供了一个非常重要的方法——Invoke。这个方法在处理多线程应用程序中的UI更新时扮演着关键角色。本文将深入探讨为什么Control类需要提供Invoke方法,以及如何正确使用它。

为什么需要Invoke方法?

1. 线程安全性

Windows Forms应用程序遵循单线程单元(Single-Threaded Apartment, STA)模型。这意味着所有UI控件都应该在创建它们的同一线程上进行访问和修改。直接从其他线程更新UI可能导致不可预知的行为,甚至应用程序崩溃。

2. 跨线程通信

在多线程应用程序中,经常需要在后台线程中执行耗时操作,然后将结果更新到UI。Invoke方法提供了一种安全的机制,允许从其他线程调用在UI线程上执行的代码。

3. 避免死锁

直接从其他线程访问UI控件可能导致死锁。Invoke方法通过正确的线程同步机制来避免这种情况。

Invoke方法的工作原理

Invoke方法的基本原理是:

  1. 接受一个委托(代表要执行的方法)作为参数。
  2. 将该委托的执行排队到UI线程。
  3. 等待UI线程执行完该委托后返回。
编辑
2025-10-06
C#
00

WinForm到WPF的转型,需要开发者从基于控件的传统概念,转变到注重界面布局、数据绑定、可视化树等全新的思路。以下主要围绕 WPF 的 Expander 控件进行实战说明,并结合对应样式与常见用法的示例进行讲解。

迁移思维:从WinForm到WPF

  • 在 WinForm 中,我们通常通过拖拽控件到窗体上,然后在属性面板中进行部分设置。

    在 WPF 中,界面更重视「布局」与「控件间的层次结构」。我们会使用 XAML 来描述界面,并通过“布局容器(如 Grid、StackPanel、DockPanel 等)”来协调控件的摆放。

  • 在 WinForm 中,样式主题化往往依靠第三方库或通用的 UI 框架。

    在 WPF 中,样式与控件模板(ControlTemplate/Style)是平台内置的能力,可以直接通过 XAML 配置,实现对外观与布局的深层定制。

Expander控件介绍

Expander 控件可以折叠或展开内容区,常用于在界面上分层展示、收起和隐藏相对不常用的子内容,以达到节省空间、提高用户交互体验的目的。

Expander 的基本结构

通常情况下,Expander 的主要结构和要点包括:

  • Header:Expander 的标题区域,会一直显示在界面上。
  • Content:Expander 的主体内容,显示在 Header 下方。可以是任何 UI 元素或容器。

下面是一个简单的 Expander 示例:

XML
<Window x:Class="AppExpander.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:AppExpander" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid Margin="10"> <!-- 在Grid内放置一个Expander --> <Expander Header="设置选项" ExpandDirection="Down" Background="AliceBlue" Foreground="Black" IsExpanded="True"> <!-- Expander折叠/展开的内容 --> <StackPanel Margin="5"> <!-- 在这里可以放置各种元素 --> <TextBlock Text="这是Expander的内容。" Margin="0,0,0,5"/> <Button Content="按钮1" Margin="0,0,0,5"/> <Button Content="按钮2"/> </StackPanel> </Expander> </Grid> </Window>

image.png

编辑
2025-10-06
C#
00

在Windows桌面开发中,WinForm曾经是主流的技术栈,但随着界面设计和交互需求越来越丰富,WPF(Windows Presentation Foundation)以更强大的UI渲染、可扩展的样式和更灵活的数据绑定特性吸引了众多开发者转向。

WinForm与WPF在绘图方面的差异

  • 渲染引擎

    WinForm基于GDI+,需要手动处理绘制逻辑、重绘、坐标转换等;WPF使用基于DirectX的矢量渲染引擎,UI可自动响应分辨率、缩放和动画等需求。

  • 布局系统

    WinForm一般使用DockAnchor或手动绝对坐标;WPF提供了丰富的布局容器(如GridStackPanelCanvas),并支持自动伸缩和自适应,大幅减少手动定位的工作量。

  • 可视化与样式

    在WinForm中对控件进行自定义样式常常需要重写OnPaint;WPF中提供了ControlTemplateStyle以及基于XAML的可视化树,能自定义任意形状、颜色和动画效果。

Ellipse的基本用法

在WPF中,Ellipse是一个通用的“图形”控件,用于绘制圆形或椭圆形。与WinForm相比,WPF中的Ellipse使用更加简单明了。

在窗口中直接使用Ellipse

下面是一个最简单的示例,展示了如何在WPF窗口中创建和使用椭圆。该示例展示了一个包含红色椭圆的窗口:

XML
<Window x:Class="AppEllipse.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:AppEllipse" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Ellipse Width="100" Height="100" Fill="Red" Stroke="Black" StrokeThickness="2" /> </Grid> </Window>

image.png

编辑
2025-10-06
C#
00

前言

在从 Windows Forms (WinForm) 转到 Windows Presentation Foundation (WPF) 的过程中,初学者常常会被全新的布局系统与控件体系所困扰。WPF 提供了许多新的控件和特性来帮助简化 UI 构建,其中一个常用控件就是 Border。本文将结合具体示例,介绍在 WPF 中如何使用 Border,并与 WinForm 的常见做法进行对比。

WinForm 与 WPF 的边框区别

  • 在 WinForm 中,自定义控件或 Panel 可能通过设置 BorderStyle 等属性来显示简单边框。要想进一步美化或调整更多外观细节,就需要借助第三方控件或自己绘制。
  • 在 WPF 中,Border 是一个专门用于为单个子元素添加边框、背景、圆角和边距的容器控件,开发者无需自行绘制即可完成丰富的样式配置。

基础用法

以下示例展示了最基本的 Border 用法,包括设置背景色、边框厚度和颜色等。

XML
<Window x:Class="AppBorder.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:AppBorder" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Border BorderThickness="2" BorderBrush="LightBlue" Background="AliceBlue" Padding="10" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Text="我是被Border包裹的内容" Foreground="DarkBlue" FontSize="16"/> </Border> </Grid> </Window>

image.png

编辑
2025-10-06
C#
00

在从 WinForm 向 WPF 转型的过程中,很多开发者都会思考如何在 WPF 中实现各种自定义图形的绘制。WinForm 中通常通过 GDI+或者直接在控件的 Paint 事件中手动绘图。而在 WPF 中,使用 Shape 派生类(例如 Rectangle, Ellipse, Line 等)就可以更直观地在界面上绘制图形。本篇文章将介绍如何在 WPF 中使用 Rectangle,并说明与 WinForm 的主要差异,以及如何利用 WPF 的强大样式和动画特性让矩形图形更灵活多变。

Rectangle 在 WinForm 与 WPF 中的差异

WinForm:

  • 通常需要在 OnPaintPaint 事件内通过 Graphics 对象手动调用 DrawRectangle 等方法进行绘制。
  • 若想改变矩形的位置、大小或颜色,通常需要触发重绘(Invalidate / Refresh)或联动其它 UI 事件。

WPF:

  • 通过 System.Windows.Shapes.Rectangle 控件来绘制矩形。可以把它看作一个 UIElement,天然支持布局系统。
  • 可直接在 XAML 中声明,或在后台代码创建并添加到容器中。
  • 可以使用依赖属性(如 Width, Height, Fill, Stroke 等)进行绑定或使用样式,轻松调整或动画化。
  • 几乎无需手动处理重绘,WPF 会自动计算并渲染界面。

一个简单的 Rectangle 示例

下面是一个最基础的示例,展示如何在 XAML 中使用 Rectangle 控件:

XML
<Window x:Class="AppRectangle.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:AppRectangle" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Rectangle Width="200" Height="100" Fill="LightBlue" Stroke="DarkBlue" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> </Window>

image.png 在此示例中: