Dean的周学习内容 24.4.22~28:Winform

什么是Winform

Winform = Windows Form = Windows 窗体  是一个可创建适用于 Windows 的丰富桌面客户端应用的 UI 框架。开发功能包括:控件(支持自定义控件)、图形、数据绑定、用户输入。

在 Windows 窗体中,窗体是一种可视图面,可在其上对用户显示信息。 通常情况下,通过向窗体添加控件和开发对用户操作(如点击鼠标或按键)的响应来生成 Windows 窗体应用。 控件是离散的 UI 元素,用于显示数据或接受数据输入。

当用户对你的窗体或一个窗体控件执行了某个操作,该操作将生成一个事件。 应用通过代码对这些事件做出反应,并在事件发生时对其进行处理。

使用 ToolStrip 和 MenuStrip 控件时,可以创建包含文本和图像的工具栏和菜单、显示子菜单和托管其他控件(如文本框和组合框)。

许多应用必须显示数据库、XML 文件、JSON 文件、Web 服务或其他数据源中的数据。 Windows 窗体提供了一个灵活的控件(名为 DataGridView 控件),用于以传统的行和列格式显示此类表格数据,以便使每段数据块均占据其自己的单元格。

通过网络连接到数据源对于 Windows 窗体而言是一个简单的任务。 BindingSource 组件表示与数据源的连接,并公开完成以下操作的方法:将数据绑定到控件、导航到上一个和下一个记录、编辑记录,以及将更改保存回原始源。 BindingNavigator 控件通过 BindingSource 组件提供一个简单界面,可供用户在记录间导航。

事件

个人认为,事件是整个Winform里最重要的部分了。哪些控件,基本上就是所见即所得,但是事件里面的东西,还是有不少逻辑的,所以这一部分需要投入较多的精力好好整一整。


//sender:发送者     参数用于传递指向事件源对象的引用。简单来讲就是当前的对象。
                    //例如button的点击事件,那么这个sender就代表这个button自己。
//EventArgs:事件参数 (EventArguments)
//object:对象,基类
private void btnError_Click(object sender, EventArgs e)
{
      //获取当前点击的Button
      Button thisClickedButton = sender as Button;
} 
           


//e参数,EventArgs  记录事件传递过来的额外信息。一般用于传递用户点击的位置啊,键盘按下的键等事件的额外信息。例如TextBox中有一个KeyPress事件。
 private void inputTextBox_KeyPress(object sender, KeyPressEventArgs e)
 {
    //获取当前对象
     TextBox tb = sender as TextBox;

      //获取当前按下来的键值
      char c = e.KeyChar;
 }

本文介绍了大多数控件共享的常见事件、用户交互引发的事件以及特定控件特有的事件。 有关 Windows 窗体中事件的详细信息,请参阅事件概述处理和引发事件。有关如何添加或删除控件事件处理程序的详细信息,请参阅如何处理事件

常用的事件

控件通过基类 Control 提供 60 多个事件。 其中包括 Paint 事件(引发控件绘制)、与显示窗口相关的事件(如 Resize 和 Layout 事件)以及低级别的鼠标和键盘事件。 某些低级别事件通过 Control 合成为语义事件,例如 Click 和 DoubleClick。 大多数共享事件属于以下类别:

  • 鼠标事件
  • 键盘事件
  • 属性更改事件
  • 其他事件
  1. Load事件:在窗体加载完成后触发,可以在该事件中进行一些初始化操作,例如设置控件的属性、加载数据等。
  2. Shown事件:在窗体显示之前触发,可以在该事件中执行一些需要在窗体显示之前完成的操作,例如显示欢迎信息、弹出提示框等。
  3. Activated事件:在窗体被激活时触发,例如当用户从其他窗体切换回当前窗体时,该事件会被触发。可以在该事件中执行一些需要在窗体激活时进行的操作。
  4. Deactivate事件:在窗体失去焦点时触发,例如当用户切换到其他窗体时,该事件会被触发。可以在该事件中执行一些需要在窗体失去焦点时进行的操作。
  5. FormClosing事件:在窗体关闭之前触发,可以在该事件中进行一些关闭前的确认或保存操作。可以通过取消事件参数来阻止窗体关闭。

鼠标事件

考虑到 Windows 窗体是一种用户界面 (UI) 技术,鼠标输入是用户与 Windows 窗体应用程序交互的主要方式。 所有控件都提供基本的鼠标相关事件:

有关详细信息,请参阅使用鼠标事件

键盘事件

如果控件响应用户输入(如 TextBox 或 Button 控件),则为此控件引发相应的输入事件。 控件必须聚焦以接收键盘事件。 某些控件(例如 Label 控件)无法聚焦,也无法接收键盘事件。 以下是键盘事件列表:

有关详细信息,请参阅使用键盘事件

属性更改事件

对于具有更改事件的属性,Windows 窗体遵循 PropertyNameChanged 模式。 Windows 窗体提供的数据绑定引擎可以识别这种模式并与之很好地集成。 创建自己的控件时,实现此模式。

此模式实现以下规则,以属性 FirstName 为例:

  • 将属性命名为:FirstName
  • 使用模式 PropertyNameChanged 为属性创建一个事件:FirstNameChanged
  • 使用模式 OnPropertyNameChanged 创建专用或受保护的方法:OnFirstNameChanged

如果 FirstName 属性集修改了后备值,则调用 OnFirstNameChanged 方法。 OnFirstNameChanged 方法引发 FirstNameChanged 事件。

以下是控件的一些常见属性更改事件:

重要活动说明
BackColorChanged当 BackColor 属性的值更改时发生。
BackgroundImageChanged当 BackgroundImage 属性的值更改时发生。
BindingContextChanged当 BindingContext 属性的值更改时发生。
DockChanged当 Dock 属性的值更改时发生。
EnabledChanged在 Enabled 属性值更改后发生。
FontChanged在 Font 属性值更改时发生。
ForeColorChanged在 ForeColor 属性值更改时发生。
LocationChanged在 Location 属性值更改后发生。
SizeChanged在 Size 属性值更改时发生。
VisibleChanged在 Visible 属性值更改时发生。

 有关事件的完整列表,请参阅控件类的“事件”部分。

其他事件

控件还将根据控件的状态或其他与控件的交互来引发事件。 例如,如果控件具有焦点并且用户按 F1 键,则会引发 HelpRequested 事件。 如果用户按窗体上的上下文相关“帮助”按钮,然后按控件上的帮助光标,则也会引发此事件。

另一个示例是更改、移动控件或重设控件大小时,会引发 Paint 事件。 此事件为开发人员提供了绘制控件并更改其外观的机会。

有关事件的完整列表,请参阅控件类的“事件”部分。

自动缩放

设计的外观可以在不同分辨率的显示器上适当显示。 如果不进行调整,针对某个分辨率设计的应用程序(特别是基于图形的应用程序)在其他分辨率上运行时就会显示太大或太小。

Windows 操作系统支持使用一种名为对话框单位的相对度量单位的自动缩放对话框。 对话框单位基于系统字体,并且它与像素的关系可由 Win32 SDK 函数 GetDialogBaseUnits 确定。 当用户更改 Windows 使用的主题时,所有对话框均自动进行相应调整。 此外,根据默认系统字体或显示分辨率,Windows 窗体支持自动缩放。 或者,可在应用程序中禁用自动缩放。

Windows 窗体使用以下逻辑自动缩放窗体及其内容:

  1. 在设计时,每个 ContainerControl 分别在 AutoScaleMode 和 AutoScaleDimensions 中记录缩放模式及其当前的分辨率。

  2. 在运行时,实际的分辨率存储在 CurrentAutoScaleDimensions 属性中。 AutoScaleFactor 属性动态计算运行时和设计时缩放分辨率之间的比率。

  3. 窗体加载时,如果 CurrentAutoScaleDimensions 和 AutoScaleDimensions 的值不同,则调用 PerformAutoScale 方法来缩放控件及其子项。 此方法将挂起布局并调用 Scale 方法来执行实际缩放。 随后将更新 AutoScaleDimensions 的值以避免渐进式缩放。

  4. 在以下情况下也可自动调用 PerformAutoScale

    • 如果缩放模式为 Font,则响应 OnFontChanged 事件。

    • 当容器控件的布局继续执行并在 AutoScaleDimensions 或 AutoScaleMode 属性中检测到更改时。

    • 如上所述,当父 ContainerControl 正在缩放时。 每个容器控件负责使用自己的比例因子(而不是其父容器的比例因子)缩放其子控件。

  5. 子控件可通过多种方式修改其缩放行为:

    • 可重写 ScaleChildren 属性以确定是否应缩放其子控件。

    • 可重写 GetScaledBounds 方法以调整控件缩放到的边界,但不是调整缩放逻辑。

    • 可重写 ScaleControl 方法以更改当前控件的缩放逻辑。

常见任务

添加窗体

有点简单,不再赘述,有需要请看这里向项目添加窗体 - Windows Forms .NET | Microsoft Learn

如何定位窗体并且重设其大小

重设大小

  1. 直接在设计器中手动拖拽
  2. 在属性中找到  Size 更改  Width 和 Height
  3. 在代码中更改大小(最不推荐!!!)但是有时候也有需要,比如点击后让窗体变小
private void button1_Click(object sender, EventArgs e) =>
    Size = new Size(250, 200);


private void button1_Click(object sender, EventArgs e)
{
    Form2 form = new Form2();
    form.Size = new Size(250, 200);
    form.Show();
}

 定位

直接在  窗体   属性中的StartPosition 修改

常见的位置如下

FormStartPosition Enum说明
CenterParent窗体在父窗体的边界内居中。(仅适用于多尔我能当界面(MDI)子窗体或使用ShowDialog方法显示的常规窗体)
CenterScreen窗体在当前显示屏中居中。
手动窗体的位置由 Location 属性决定。
WindowsDefaultBounds窗体位于 Windows 默认位置,且大小重设为 Windows 决定的默认大小。
WindowsDefaultLocation窗体位于 Windows 默认位置,没有重设大小。

 当然,也可以使用代码定位

移动当前窗体

private void button1_Click(object sender, EventArgs e) =>
    Location = new Point(0, 0);

定位其他窗体

private void button1_Click(object sender, EventArgs e)
{
    Form2 form = new Form2();
    form.Location = new Point(0, 0);
    form.Show();
}

控件

控件:可重用的组件,封装用户界面功能并用于基于 Windows 的客户端应用程序。 Windows 窗体不仅可以提供许多易用的控件,而且还可以提供用于开发你自己的控件的基础结构。

布局

在父级上的位置由父级表面左上角的 Location 属性的值确定

控件事件

通过基类 Control 提供 60 多个事件。 其中包括 Paint 事件(引发控件绘制)、与显示窗口相关的事件(如 Resize 和 Layout 事件)以及低级别的鼠标和键盘事件。 某些低级别事件通过 Control 合成为语义事件,例如 Click 和 DoubleClick。 大多数共享事件属于以下类别:

  • 鼠标事件
  • 键盘事件
  • 属性更改事件
  • 其他事件

并非每个控件都响应每个事件。 例如,Label 控件不响应键盘输入,因此不会引发事件 Control.PreviewKeyDown

控件通常是下层 Win32 控件的包装器,并且使用 Paint 事件在控件顶部绘制可能会受到限制或根本无法执行任何操作,因为控件最终是由 Windows 绘制的。

控件赋值功能

Windows 窗体具有对屏幕阅读器的辅助功能支持和用于口头命令的语音输入实用工具。 但是,在设计 UI 时必须考虑到辅助功能。 Windows 窗体控件公开各种属性来处理辅助功能。 有关这些属性的详细信息,请参阅提供控件辅助功能信息

控件的位置和布局

一些基本的东西(固定位置和大小、Margin和Padding区别、自动放置和大小)不赘述了,想了解的可以看这个文档:控件布局选项 - Windows Forms .NET | Microsoft Learn

拖动顺序可影响自动放置。

其他的一些我认为稍微高级那么一丢丢的整理了一下:

靠接(Dock)

设置控件的哪个边与父级的对应边对齐,以及如何在父级中调整控件的大小。

先后顺序会影响 Z-order

这个是先设置了Top,后设置了Left,left控件占的空间会更少

这个就是先设置了Left,后设置了Top,TOP控件占的空间会更少

随着容器增大和缩小,停靠在容器上的控件将重新定位并调整大小,以保持其位置和大小处于适当状态。

多个控件停靠在同一侧,则根据其位置将其堆叠

定位点(Anchor)

将控件绑定到父级容器的一侧或多侧。 容器尺寸发生变化时,任何子级控件都将保持其与定位侧的距离。

自动调整大小 

可使用 AutoSize 属性更改控件的大小,以适应 PreferredSize 属性指定的大小。 可通过设置 AutoSizeMode 属性来调整特定控件的调整大小行为。

仅部分控件支持 AutoSize 属性。 此外,支持 AutoSize 属性的某些控件也支持 AutoSizeMode 属性。

Always true 行为说明
自动调整大小是一种运行时间功能。这意味着它永远不会增大或缩小控件,因此不会产生进一步的影响。
即使控件更改大小,它的 Location 属性的值也始终保持不变。控件的内容导致控件增大时,控件将向右和向下扩展。 控件不会向左侧扩展。
AutoSize 为 true 时,采用 Dock 和 Anchor 属性。控件的 Location 属性的值将调整为正确值。

Label 控件是此项规则的例外情况。 将停靠的 Label 控件的 AutoSize 属性的值设置为 true 时,Label 控件将不会拉伸。
无论控件的 AutoSize 属性的值如何,始终采用其 MaximumSize 和 MinimumSize 属性。MaximumSize 和 MinimumSize 属性不受 AutoSize 属性的影响。
默认情况下,不设置最小大小。这意味着,如果在 AutoSize 下方将控件设置为缩小,且不包含任何内容,则其 Size 属性的值为 (0x,0y)。 在这种情况下,控件将缩小为点,且不明显可见。
如果控件未实现 GetPreferredSize 方法,则 GetPreferredSize 方法将返回分配给 Size 属性的最后一个值。这意味着将 AutoSize 设置为 true 无效。
TableLayoutPanel 单元格中的控件始终会缩小以适应单元格,直到达到其 MinimumSize此大小强制作为最大大小。 如果单元格属于 AutoSize 行或列,则不会出现这种情况。

 AutoSizeMode 属性

提供对默认 AutoSize 行为更精细的控制。指定控件自行调整大小以适应其内容。例如,内容可以是 Button 控件的文本或容器的子控件。

支持AutoSize属性的控件

Button
CheckedListBox
FlowLayoutPanel
Form
GroupBox
Panel
TableLayoutPanel
CheckBox
DomainUpDown
Label
LinkLabel
MaskedTextBox
NumericUpDown
RadioButton
TextBox
TrackBar
CheckedListBox
ComboBox
DataGridView
DateTimePicker
ListBox
ListView
MaskedTextBox
MonthCalendar
ProgressBar
PropertyGrid
RichTextBox
SplitContainer
TabControl
TabPage
TreeView
WebBrowser
ScrollBar

设计环境中的AutoSize

在设计时基于控件的 AutoSize 和 AutoSizeMode 属性的值调整其大小的行为。

重写 SelectionRules 属性以确定给定控件是否处于用户可调整大小的状态。 在下表中,“无法调整大小”仅表示 Moveable,“可以调整大小”表示 AllSizeable 和 Moveable

AutoSize 设置AutoSizeMode 设置行为
true属性不可用。用户无法在设计时调整控件的大小,以下控件除外:

TextBox
MaskedTextBox
RichTextBox
TrackBar
trueGrowAndShrink用户无法在设计时调整控件的大小。
trueGrowOnly用户可以在设计时调整控件的大小。 设置 Size 属性后,用户只能增加控件的大小。
已隐藏 false 或 AutoSize不适用。用户可以在设计时调整控件的大小。

为了最大限度地提高工作效率,Visual Studio 中的 Windows 窗体设计器将隐藏 Form 类的 AutoSize 属性。 在设计时,窗体的行为如同 AutoSize 属性设置为 false,而不考虑其实际设置如何。 在运行时,不会进行特殊调整,并且会按照属性设置指定的方式应用 AutoSize 属性。

面板(Panel)

类似于直接将控件组合在一起的窗体,它支持窗体所支持的手动和自动放置样式。没有描述文字(与 分组框 控件不同)

面板与父级无缝相融,并切断超出面板边界的控件的任何区域。 如果控件在面板边界之外,且 AutoScroll 设置为 true,则会显示滚动条,并且用户可以滚动面板。

此处设置了BorderStyle属性,用来演示面板的边界

分组框(GroupBox)

分组框有名称、为其他控件提供可识别分组。 通常,可使用分组框按功能细分窗体。 例如,窗体可能显示个人信息,并且与地址有关的字段将组合在一起。 设计时,可轻松移动分组框及其包含的控件。

流布局(FlowLayoutPanel)

FlowLayoutPanel 控件沿水平或纵排方向排列其内容。 可从一行到下一行,或从一列到下一列来进行控件内容换行。 或者,可以剪切其内容,而非进行换行。

设置 FlowDirection 属性的值来指定排列方向、设置 WrapContents 属性的值来指定是对 FlowLayoutPanel 控件的内容进行换行还是剪切。
子控件有 FlowBreak 属性。 将 FlowBreak 属性的值设置为 true 会使 FlowLayoutPanel 控件停止按当前排列方向对控件进行布局,并换行到下一行或下一列。

表格布局(TableLayoutPanel)

其内容排列在网格中、布局是同时在设计时和运行时执行的,因此它可随应用程序环境的变化而动态地变化

任何 Windows 窗体控件均可以是 TableLayoutPanel 控制的子控件,包括 TableLayoutPanel 的其他实例。 这使你可以构造适应在运行时发生更改的复杂布局。

在 TableLayoutPanel 控件充满子控件后,还可控制扩展的方向(水平或垂直)。 默认情况下,TableLayoutPanel 控件通过添加行向下扩展。

可以使用 RowStyles 和 ColumnStyles 属性来控制行和列的大小和样式。 可分别设置行或列的属性。TableLayoutPanel 控件将以下属性添加到其子控件中:CellColumnRow、ColumnSpan 和RowSpan

拆分容器(SplitContainer)

这个控件可以看做一个符合控件:由可移动条隔开的两个面板,鼠标指针位于条上方时,指针将改变性转杠一表示条可以移动。

SplitContainer 控件可用于创建复杂的用户界面;通常情况下,在一个面板中的选择将决定显示在另一个面板中的对象。 这种安排对于显示和浏览信息有效。 拥有两个面板使你能够在区域、条或“拆分器”中聚合信息,使用户可轻松地调整面板大小。

 

选项卡控件(TabControl)

TabControl 显示多个选项卡,就像笔记本中的分隔线或档案柜中一组文件夹的标签。 选项卡可以包含图片和其他控件。 使用选项卡控件可生成多页对话框,该对话框可在 Windows 操作系统中的许多位置显示,例如“控制面板”和“显示属性”。 此外,TabControl 可用于创建属性页面,该页面用于设置一组相关属性。

TabControl 最重要的属性是 TabPages,其中包含各个选项卡。 每个选项卡都是 TabPage 对象。

自定义控件

自定义控件有三种类型:用户控件(复合控件)、扩展控件、自定义控件

  • 你想要将多个 Windows 窗体控件的功能组合到单个可重用单元。
通过从 System.Windows.Forms.UserControl 继承来设计用户控件
  • 大部分所需功能与现有的 Windows 窗体控件相同。
  • 你不需要自定义图形用户界面,或者想为现有控件设计一个新的图形用户界面
通过从某一特定 Windows 窗体控件继承来扩展控件
  • 你想要提供控件的自定义图形表示形式。
  • 你需要实现不能通过标准控件实现的自定义功能
通过从 System.Windows.Forms.Control 继承来创建自定义控件

用户控件

包含每个子控件的所有固有功能、允许选择性的公开和绑定他们的属性、提供了大量默认键盘处理功能。

例如,可以生成用户控件,以显示来自数据库的客户地址数据。 此控件将包括用于显示数据库字段的 DataGridView 控件、用于处理到数据源的绑定的 BindingSource,以及用于在记录之间移动的 BindingNavigator 控件。 可以选择性地公开数据绑定属性,还可以将整个控件打包并在不同应用程序之间重复使用。

有关详细信息,请参阅用户控件概述

注意

用户控件在定义事件时需要有一些注意事项:

  • 定义没有任何关联数据的事件时,请使用 EventHandler 事件委托。 在你拥有关联数据时,请使用 EventHandler<TEventArgs> 事件委托。
  • 在引发具有关联数据的事件时,从 EventArgs 派生并用你的数据扩展它。
  • 将控件实例作为 sender 参数传递。
  • 创建一个名为 On{EventName} 的方法,该方法引发事件,该事件被标记为 protected 和 virtual(在 C# 中)或 Protected 和 Overridable(在 Visual Basic 中)。
// The event
public event EventHandler AllowInteractionChanged;

// The backing field for the property
private bool _allowInteraction;

// The property
public bool AllowInteraction
{
    get => _allowInteraction;
    set
    {
        // When the value has changed, call the method to raise the event
        if (_allowInteraction != value)
        {
            _allowInteraction = value;
            OnAllowInteractionChanged();
        }
    }
}

// Raises the event
public virtual void OnAllowInteractionChanged() =>
    AllowInteractionChanged?.Invoke(this, EventArgs.Empty);

如果希望控件在属性更改时发送通知,请定义名为 {PropertyName}Changed 的事件。 这是 Windows 窗体中使用的命名约定。 属性更改事件的关联事件委托类型是 EventHandler,该事件数据类型是 EventArgs。 基类 Control 定义许多属性更改事件,例如 BackColorChangedBackgroundImageChangedFontChangedLocationChanged。 当属性遵循此命名约定时,它会收到双向数据绑定支持。

定义事件一节中的相同建议也适用于此处。

public class ProgressReportEventArgs : EventArgs
{
    public readonly int Value;
    public readonly int Maximum;

    public ProgressReportEventArgs(int value, int maximum) =>
        (Value, Maximum) = (value, maximum);
}

public event EventHandler<ProgressReportEventArgs> ProgressChanged;

public virtual void OnProgressChanged(int value, int maximum) =>
    ProgressChanged?.Invoke(this, new ProgressReportEventArgs(value, maximum));

控件属性应支持 Windows 窗体可视化设计器。 “属性”窗口与控件属性交互,用户希望使用此窗口更改控件的属性。 将 DefaultValueAttribute 添加到属性,或创建相应的 Reset<PropertyName> 和 ShouldSerialize<PropertyName> 方法。 有关详细信息,请参阅 DefaultValueAttribute 和 Reset 和 ShouldSerialize

不希望向 Windows 窗体可视化设计器公开的属性应向该属性添加 BrowsableAttribute,为特性的参数传递 false。 这会在“属性”窗口中隐藏该属性。 有关详细信息,请参阅定义属性属性的特性

实例

如何创建用户控件 - Windows Forms .NET | Microsoft Learn,跟着做了,也确实做出来了。总结一下,好像挺简单的,新建用户控件,然后往用户空间里拖拽已有的控件,新添加一些属性,注意添加需要的特性。然后再绑定事件,然就就可以用了。

扩展控件

从任何现有的 Windows 窗体控件派生继承的控件。 使用此方法,你可以保留 Windows 窗体控件的所有固有功能,然后通过添加自定义属性、方法或其他功能来扩展该功能。 可以使用此选项重写基控件的绘制逻辑,然后通过更改该控件的外观来扩展其用户界面。

例如,可以创建一个由 Button 控件派生的控件,并用它来跟踪用户的单击次数。

在某些控件中,也可以通过重写基类的 OnPaint 方法为控件的图形用户界面添加自定义外观。 对于跟踪单击次数的扩展按钮,可以重写 OnPaint 方法以调用 OnPaint 的基实现,然后在 Button 控件的工作区的一角绘制单击计数

自定义控件

从 Control 继承,从头开始充分创建一个控件。

相比从 UserControl 或现有 Windows 窗体控件继承来说,通过从 Control 类继承来创建控件需要花费更多心思和精力。 由于用户还需执行大量的实现,因此,控件可以具有比复合控件或扩展控件更好的灵活性,而且可以使控件完全满足自己的需要。

要实现自定义控件,必须为控件的 OnPaint 事件编写代码,它控制着控件的视觉绘制方式。 还必须为控件编写任何特定于功能的行为。 还可以重写 WndProc 方法并直接处理窗口消息。 这是创建控件的最强大的方法,但若要有效地使用此技术,需熟悉 Microsoft Win32® API。

时钟控件即是一个自定义控件,它复制模拟时钟的外观和行为。 调用自定义绘制来使指针移动,以响应来自内部 Timer 组件的 Tick 事件。

自定义设计体验

自定义现有控件 - Windows Forms .NET | Microsoft Learn 尝试跟着敲一遍吧😀

自己跟着试了一遍,emmmm,为什么会失败呢,再跟着这个试试,晓得了,编译之后,应该去别的地方拖拽进入控件  ok了。WinFrom C#自定义控件的实现与添加流程_c# 自定义控件制作步骤以及编译结果-CSDN博客

如果需要实现自定义设计时体验,可以创作自己的设计器。 对于复合控件,从 ParentControlDesigner 或 DocumentDesigner 类派生自定义设计器类。 对于扩展控件和自定义控件,从 ControlDesigner 类派生自定义设计器类。

使用 DesignerAttribute 将控件与设计器关联。

以下信息已过时,但可能会对你有所帮助。

用户输入----键盘

Windows 窗体提供了两个在用户按下键盘键时发生的事件和一个在用户释放键盘键时发生的事件:

  • KeyDown 事件发生一次。
  • 用户按住相同的键时,KeyPress 事件可发生多次。
  • 用户释放某个键时,KeyUp 事件发生一次。

用户按某个键时,Windows 窗体会根据键盘消息指定的是字符键还是物理键来确定引发哪个事件。 有关字符键和物理键的详细信息,请参阅键盘概述、键盘事件

键盘事件说明结果
KeyDown用户按下物理键时,引发此事件。KeyDown 的处理程序接收:
 
KeyPress当所按的某个键或多个键生成一个字符时,则引发此事件。 例如,用户按 SHIFT 和小写的“a”键将会生成大写字母“A”字符。KeyPress 在 KeyDown 后引发。
 
  • KeyPress 的处理程序接收:
  • 一个 KeyPressEventArgs 参数,它包含所按的键的字符代码。 此字符代码对每个字符键和修改键组合都是唯一的。

    例如,“A”键将生成:
     
    • 字符代码 65(如果与 SHIFT 键一起按下)
    • 或 CAPS LOCK 键 97(如果单独按下),
    • 以及 1(如果与 CTRL 键一起按下)。
KeyUp用户释放物理键时,将引发此事件。KeyUp 的处理程序接收:
 
  • 一个 KeyEventArgs 参数:
     
    • 它提供 KeyCode 属性(该属性指定一个物理键盘按钮)。
    • Modifiers 属性(SHIFT、CTRL 或 ALT)。
    • KeyData 属性(它结合了键代码和修饰符)。

所有 Windows 窗体控件都将继承与鼠标和键盘输入相关的一组事件。 例如,控件可以处理 KeyPress 事件以确定所按下的键的字符代码。

窗体和控件可以访问 IMessageFilter 接口和一组可重写的方法,这些方法可在消息队列中的不同位置处理 Windows 消息。 这些方法都有 Message 参数,该参数用于封装 Windows 消息的低级别详细信息。 可以实现或重写这些方法来检查消息,然后使用此消息或将其传递给消息队列中的下一个使用者。 下表显示用于处理 Windows 窗体中所有 Windows 消息的方法。

PreFilterMessage此方法在应用程序级别截获排队的(也称为已发布的)Windows 消息。
PreProcessMessage此方法在 Windows 消息经过处理之前,在窗体和控件级别截获这些消息。
WndProc此方法在窗体和控件级别处理 Windows 消息
DefWndProc此方法在窗体和控件级别执行 Windows 消息的默认处理。 这提供了窗口的最小功能。
OnNotifyMessage此方法在消息经过处理之后,在窗体和控件级别截获这些消息。 必须设置 EnableNotifyMessage 样式位才能调用此方法。

键盘和鼠标消息也由其他一组特定于这些类型消息的可重写方法进行处理。 有关详细信息,请参阅键的预处理部分。 

密钥类型

Windows 窗体将键盘输入标识为由按位 Keys 枚举表示的虚拟键代码。 使用 Keys 枚举,可以组合一系列按键以生成单个值。 这些值与 WM_KEYDOWN 和 WM_SYSKEYDOWN Windows 消息所附带的值相对应。 可以通过处理 KeyDown 或 KeyUp 事件来检测大多数物理按键。 字符键是 Keys 枚举的子集,它们与 WM_CHAR 和 WM_SYSCHAR Windows 消息所附带的值相对应。 如果通过组合按键得到一个字符,则可以通过处理 KeyPress 事件来检测该字符。

键盘事件顺序

正如上面列出的那样,在一个控件上可能出现三个与键盘相关的事件。 以下顺序是发生这些事件的常规顺序:

  1. 用户按“a”键,该键将被预处理和调度,并且会发生 KeyDown 事件。
  2. 用户按住“a”键,该键将被预处理和调度,并且会发生 KeyPress 事件。 当用户按住某个键时,此事件会发生多次。
  3. 用户松开“a”键,该键将被预处理和调度,并且会发生 KeyUp 事件。

键的预处理

与其他消息一样,键盘消息也是在窗体或控件的 WndProc 方法中处理的。 但是,在处理键盘消息之前,PreProcessMessage 方法会调用一个或多个方法,这些方法可被重写以处理特殊的字符键和物理按键。 可以重写这些方法,以便在控件处理消息之前检测并筛选某些按键。 下表按照方法出现的顺序列出了正在执行的操作以及所出现的相关方法。

KeyDown 事件的预处理

操作相关方法说明
检查是否为命令键(如快捷键或菜单快捷键)。ProcessCmdKey此方法处理命令键,命令键的优先级高于常规键。 如果此方法返回 true,则不调度键消息,而且不发生键事件。 如果它返回 false,则调用 IsInputKey
检查该键是否为需要预处理的特殊键,或者是否为应引发 KeyDown 事件并且被调度到某个控件的普通字符键。IsInputKey如果此方法返回 true,则表示该控件为常规字符,并且会引发 KeyDown 事件。 如果返回 false,则调用 ProcessDialogKey。 注意:若要确保控件获取某个键或组合键,可以处理 PreviewKeyDown 事件,并针对所需的键或组合键将 PreviewKeyDownEventArgs 的 IsInputKey 设置为 true
检查该键是否为导航键(Esc、Tab、回车键或箭头键)。ProcessDialogKey此方法处理在控件内实现特殊功能(如在控件与其父级之间切换焦点)的物理按键。 如果中间控件不处理该键,则会调用父控件的 ProcessDialogKey,直至层次结构中的最顶端控件。 如果此方法返回 true,则完成预处理,而且不生成按键事件。 如果它返回 false,则会发生 KeyDown 事件。

KeyPress事件的预处理

操作相关方法说明
检查该键是否为控件应当处理的普通字符IsInputChar如果该字符是普通字符,则此方法返回 true,并且引发 KeyPress 事件,而且不再进行预处理。 否则,将调用 ProcessDialogChar
检查该字符是否为助记键(如按钮上的“确定(&O)”)ProcessDialogChar与 ProcessDialogKey 类似,将调用此方法,直至控件层次结构的顶端。 如果控件是容器控件,此方法会通过调用控件及其子控件的 ProcessMnemonic 来检查助记键。 如果 ProcessDialogChar 返回 true,则不会发生 KeyPress 事件。

处理键盘消息

键盘消息在到达窗体或控件的 WndProc 方法之后,它们会由一组可重写的方法来处理。 其中的每种方法都返回一个 Boolean 值,该值指定控件是否已处理和使用了键盘消息。 如果其中的某种方法返回 true,则键盘消息被视为已处理,而且它不传递到控件的基控件或父控件进行进一步处理。 否则,消息停留在消息队列中,而且可能会在控件的基控件或父控件的其他方法中进行处理。 下表显示用来处理键盘消息的方法。

方法说明
ProcessKeyMessage此方法处理由控件的 WndProc 方法接收的所有键盘消息。
ProcessKeyPreview此方法将键盘消息发送到控件的父控件。 如果 ProcessKeyPreview 返回 true,则不生成键事件,否则将调用 ProcessKeyEventArgs
ProcessKeyEventArgs此方法会根据需要引发 KeyDownKeyPress 和 KeyUp 事件。

重写键盘方法

 在预处理和处理键盘消息时,可以使用许多方法进行重写;但是,这些方法有好有坏。 下表显示可能需要完成的任务以及重写键盘方法的最佳方式。 有关重写方法的详细信息,请参阅继承(C# 编程指南)继承 (Visual Basic)

任务方法
截获导航键并引发 KeyDown 事件。 例如,希望在文本框中处理 Tab 键和回车键。重写 IsInputKey。 注意:还可以处理 PreviewKeyDown 事件,并针对所需的键或组合键将 PreviewKeyDownEventArgs 的 IsInputKey 设置为 true
在控件上执行特殊的输入或导航处理。 例如,你可能希望在列表控件中使用箭头键更改选定项。重写 ProcessDialogKey
截获导航键并引发 KeyPress 事件。 例如,你希望在数字调整框控件中,多次按箭头键来加快项的调整进度。重写 IsInputChar
在 KeyPress 事件期间执行特殊的输入或导航处理。 例如,在列表控件中,按住“r”键将跳到以字母 r 开头的项并在这些项间切换。重写 ProcessDialogChar
执行自定义的助记键处理;例如,你希望处理所有者描述的、包含在工具栏中的按钮上的助记键。重写 ProcessMnemonic

 验证输入内容

MaskedTextBox 控件

如果需要用户以明确定义的格式输入数据,例如电话号码或零件编号,则可以使用 MaskedTextBox 控件以最少的代码快速实现此目的。 掩码是由掩码语言中的字符组成的字符串,用于指定可在文本框中的任何特定位置输入的字符。 控件向用户显示一组提示。 如果用户键入错误条目(例如,用户在需要输入数字时键入字母),则控件将自动拒绝输入。

MaskedTextBox 使用的掩码语言是灵活的。 它允许指定必填字符、可选字符、文本字符(例如连字符和括号)、货币字符和日期分隔符。 控件绑定到数据源时也可以正常工作。 可使用数据绑定上的 Format 事件重格式化输入数据,使其符合掩码;可使用 Parse 事件重格式化输出数据,使其符合数据字段的规范。

事件驱动的验证

......(明天再说,今天看了一天的Winform  换换脑子😀24.4.24)

今天继续!

通过使用控件内置的验证事件,可以进行复杂的验证检查,通过 Validating 事件,

在 Validating 事件处理方法中,可以通过多种方式验证用户输入。 例如,如果文本框必须包含邮政编码,则可以通过以下方式进行验证:(主要是正则表达式

  • 如果邮政编码必须属于特定的邮政编码组,则可以对输入进行字符串比较,以验证用户输入的数据。 例如,如果邮政编码必须属于集合 {10001, 10002, 10003},则可以进行字符串比较来验证数据。

  • 如果邮政编码必须采用特定格式,则可以使用正则表达式来验证用户输入的数据。 例如,若要验证格式 ##### 或 #####-####,可以使用正则表达式 ^(\d{5})(-\d{4})?$。 若要验证格式 A#A #A#,可以使用正则表达式 [A-Z]\d[A-Z] \d[A-Z]\d。 有关正则表达式的详细信息,请参阅 .NET 正则表达式正则表达式示例

  • 如果邮政编码必须是有效的美国邮政编码,则可以调用邮政编码 Web 服务来验证用户输入的数据。

Validating 事件由类型为 CancelEventArgs 的对象提供。 如果确定控件的数据无效,可将此对象的 Cancel 属性设置为 true,以取消 Validating 事件。 如果未设置 Cancel 属性,则 Windows 窗体将假定针对该控件的验证成功,并引发 Validated 事件。

验证的数据绑定

使用数据绑定时,控件中的数据会在 Validating 事件执行期间与数据源同步。 如果取消 Validating 事件,则数据不会与数据源同步。

隐式和显式的验证

隐式验证:焦点移开控件时,进行数据验证。将该控件的 AutoValidate 属性设置为 EnablePreventFocusChange 或 EnableAllowFocusChange 就是了。

显示转换:点击下一步操作的时候进行验证

发生用户操作时,可以通过以下方式之一触发显式验证:

  • 调用 Validate 以验证最后一个控件是否失去焦点。
  • 调用 ValidateChildren 以验证窗体或容器控件中的所有子级控件。
  • 调用自定义方法,以手动验证控件中的数据。

关闭窗体和重写验证

控件保持焦点时,由于其所包含的数据无效,因此无法通过以下常用方法之一关闭父级窗体:

  • 单击“关闭”按钮。
  • 选择“系统”>“关闭”菜单。
  • 以编程方式调用 Close 方法。

但在某些情况下,无论控件中的值是否有效,均建议让用户关闭窗体。 可以通过为窗体的 FormClosing 事件创建处理程序来重写验证并关闭仍包含无效数据的窗体。 在事件中,将 Cancel 属性设置为 false。 这将强制关闭窗体。 有关详细信息及示例,请参阅Form.FormClosing

组合键的使用

用户可能会需要使用修改键如 SHIFT、ALT 和 CTRL。 当修改键与其他键甚至是鼠标单击一起按下时,应用程序可以相应地做出响应。 例如,按 S 键可能会在屏幕上显示一个“s”。 如果按下键 CTRL+S,可能会保存当前文档。

处理 KeyDown 事件:事件处理程序收到的 KeyEventArgs.Modifiers 属性将指定按下的修改键。 此外,KeyEventArgs.KeyData 属性指定与按位 OR 组合的所有修改键一起按下的字符。

处理 KeyPress 事件 / 鼠标事件: 使用 Control 类的 ModifierKeys 属性来检测修改键。 在任一情况下,都必须对相应的 Keys 值和要测试的值执行按位 AND。 Keys 枚举提供每个修改键的变体,因此,请务必使用正确的值执行按位 AND 检查。

// Event only raised when non-modifier key is pressed
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
        MessageBox.Show("KeyPress " + Keys.Shift);
}

// Event raised as soon as shift is pressed
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
        MessageBox.Show("KeyDown " + Keys.Shift);
}

窗体级别处理输入

处理有效窗体的 KeyPress 或 KeyDown 事件,并将该窗体的 KeyPreview 属性设置为 true。 此属性会使键盘消息在到达窗体上的任何控件之前就被窗体接收。 以下代码示例通过检测所有数字键并使用 1、4 和 7 来处理 KeyPress 事件。

// Detect all numeric characters at the form level and consume 1,4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar >= 48 && e.KeyChar <= 57)
    {
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");

        switch (e.KeyChar)
        {
            case (char)49:
            case (char)52:
            case (char)55:
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
                e.Handled = true;
                break;
        }
    }
}

模拟键盘事件

Windows 窗体提供 System.Windows.Forms.SendKeys 类,用于向活动应用程序发送击键。有两种方式模拟

  1. SendKeys.Send  :   不阻止当前线程
  2.  SendKeys.SendWait :   发送时会阻止当前线程,等待响应

如果 SendKeys 类使用新的实现,在将击键发送到其他应用程序时,SendWait 方法不再阻止当前线程。

可以模拟键盘将 Key 发送给同应用或者其他应用

这里好像没有看太懂

鼠标事件

当用户移动鼠标时,操作系统将移动鼠标指针。 鼠标指针包含一个称为“热点”的像素,操作系统会跟踪该像素并将其识别为指针的位置。 当用户移动鼠标或按下鼠标按钮时,包含 HotSpot 的 Control 将引发相应的鼠标事件。

 在处理鼠标事件时使用 MouseEventArgs 的 Location 属性获取当前鼠标位置,也可使用 Cursor 类的 Position 属性获取当前鼠标位置。 然后可使用鼠标位置信息来执行命中测试,然后根据鼠标的位置执行操作。 命中测试功能内置于 Windows 窗体中的若干控件,如 ListViewTreeViewMonthCalendar 和 DataGridView 控件。 

更改鼠标的输入位置

通过从控件派生并使用 GetStyle 和 SetStyle 方法,检测并更改控件处理鼠标输入的方式。 

 SetStyle 方法使用 ControlStyles 值的按位组合来确定控件是否将具有标准单击、双击行为,或控件是否将处理自己的鼠标处理。

此外,SystemInformation 类还包括描述鼠标功能以及指定鼠标与操作系统交互方式的属性。 下表对这些属性进行了总结。

properties说明
DoubleClickSize获取如下区域的尺寸(以像素为单位):用户必须在此区域内单击两次,操作系统才将这两次单击视为一次双击。
DoubleClickTime获取要将鼠标操作视为双击的第一次单击与第二次单击之间可以经过的最大毫秒数。
MouseButtons获取鼠标上的按钮数。
MouseButtonsSwapped获取一个值,该值指示是否已交换鼠标左右按钮的功能。
MouseHoverSize获取特定矩形的尺寸(以像素为单位),鼠标指针必须在该矩形范围内停留达到鼠标悬停时间后,才会生成鼠标悬停消息。
MouseHoverTime获取一个以毫秒为单位的时间,鼠标指针必须在悬停矩形中停留该时间后,才会生成鼠标悬停消息。
MousePresent获取一个值,该值指示鼠标是否已安装。
MouseSpeed获取一个值,该值指示当前鼠标速度,范围为 1 至 20。
MouseWheelPresent获取一个值,该值指示是否安装了带有鼠标轮的鼠标。
MouseWheelScrollDelta获取单次鼠标轮旋转增量的增量值。
MouseWheelScrollLines获取滚动鼠标轮时所滚动过的行数。

鼠标事件

Click此事件在释放鼠标按钮时发生,通常在 MouseUp 事件之前。 此事件的处理程序接收类型为 EventArgs 的参数。 如果只需确定何时发生单击,处理此事件。
MouseClick此事件在用户使用鼠标单击控件时发生。 此事件的处理程序接收类型为 MouseEventArgs 的参数。 如果需要在发生单击时获取有关鼠标的信息,处理此事件。
DoubleClick此事件在双击控件时发生。 此事件的处理程序接收类型为 EventArgs 的参数。 如果只需确定何时发生双击,处理此事件。
MouseDoubleClick此事件在用户使用鼠标双击控件时发生。 此事件的处理程序接收类型为 MouseEventArgs 的参数。 如果需要在发生双击时获取有关鼠标的信息,处理此事件。
MouseDown当鼠标指针位于控件上方并且用户按下鼠标按钮时,会发生此事件。 此事件的处理程序接收类型为 MouseEventArgs 的参数。
MouseEnter当鼠标指针进入控件的边框或工作区时(具体取决于控件的类型),会发生此事件。 此事件的处理程序接收类型为 EventArgs 的参数。
MouseHover此事件在鼠标指针停留在控件上时发生。 此事件的处理程序接收类型为 EventArgs 的参数。
MouseLeave当鼠标指针离开控件的边框或工作区时(具体取决于控件的类型),会发生此事件。 此事件的处理程序接收类型为 EventArgs 的参数。
MouseMove当鼠标指针发生移动但仍位于控件上方时,会发生此事件。 此事件的处理程序接收类型为 MouseEventArgs 的参数。
MouseUp当鼠标指针位于控件上方,并且用户释放鼠标按钮时,会发生此事件。 此事件的处理程序接收类型为 MouseEventArgs 的参数。
MouseWheel当用户滚动鼠标滚轮并且控件有焦点时,会发生此事件。 此事件的处理程序接收类型为 MouseEventArgs 的参数。 可以使用 MouseEventArgs 的 Delta 属性来确定鼠标滚动的距离。

MouseEventArgs 将发送到与单击鼠标按钮和跟踪鼠标移动相关的鼠标事件处理程序。 MouseEventArgs 提供有关当前鼠标状态的信息,包括鼠标指针在客户端坐标中的位置、按下的鼠标按钮是哪一个以及是否已经滚动鼠标滚轮。 几个鼠标事件(例如在鼠标指针进入或离开控件边界时引发的事件)会向事件处理程序发送 EventArgs,但不提供详细信息。

标准Click事件行为

使用鼠标事件 - Windows Forms .NET | Microsoft Learn  看这个文档就可以了,有点多和杂,后面有需要的话再仔细研究也不迟

拖放功能

DragEnter将对象拖入控件的边界时此事件发生。 此事件的处理程序接收类型为 DragEventArgs 的参数。
DragOver在鼠标指针位于控件的边界内时如果拖动对象则此事件发生。 此事件的处理程序接收类型为 DragEventArgs 的参数。
DragDrop拖放操作完成时此事件发生。 此事件的处理程序接收类型为 DragEventArgs 的参数。
DragLeave将对象拖出控件的边界时此事件发生。 此事件的处理程序接收类型为 EventArgs 的参数。

其他的比如,区分单击和双击、控制和修改鼠标指针、模拟鼠标事件等内容,还是去看微软的文档吧,自己暂时也用不到

数据绑定

在 Windows 窗体中,你不仅可以绑定到传统的数据源,还可以绑定到几乎任何包含数据的结构。 可以绑定到你在运行时、从文件读取时或从其他控件的值派生时计算的一数组值。

此外,你可将任何控件的任何属性绑定到数据源。 在传统数据绑定中,你通常将显示属性(例如 Text 控件的 TextBox 属性)绑定到数据源。 通过 .NET,你还可选择通过绑定来设置其他属性。 你可以使用绑定来执行以下任务:

  • 设置图像控件的图形。

  • 设置一个或多个控件的背景色。

  • 设置控件的大小。

从根本上讲,数据绑定是一种设置窗体上任何控件的任何运行时可访问属性的自动方法。

数据绑定相关的接口:ADO.NET 

数据绑定接口的使用者有两种,分别是:要由数据源作者实现的接口、

数据源作者实现的接口

IList、IBindingList、IBindingListView、IEditableObject、

IList 接口、IBindingList 接口、IBindingListView 接口、IEditableObject 接口、ICancelAddNew 接口、IDataErrorInfo 接口、IEnumerable 接口、ITypedList 接口、ICustomTypeDescriptor 接口、IListSource 接口、IRaiseItemChangedEvents 接口、ISupportInitialize 接口、ISupportInitializeNotification 接口、INotifyPropertyChanged 接口

要由组件作者实现的接口

IBindableComponent 接口、ICurrencyManagerProvider 接口

数据绑定的类型说明
简单数据绑定控件绑定到单个数据元素(如数据集表的列中的值)的能力。 简单数据绑定是 TextBox 控件或 Label 控件等控件(即通常只显示单个值的控件)的典型绑定类型。 事实上,控件上的任何属性都可以绑定到数据库中的字段。 Visual Studio 中提供对此功能的广泛支持。

有关详细信息,请参阅导航数据创建简单绑定控件(Windows 窗体 .NET)
复杂数据绑定控件绑定一个以上数据元素(通常为一个数据库中的一个以上的记录)的能力。 复杂绑定也称基于列表的绑定。 支持复杂绑定的控件示例为 DataGridViewListBox 和 ComboBox 控件。 有关复杂数据绑定的示例,请参阅如何:将 Windows 窗体 ComboBox 控件或 ListBox 控件绑定到数据

为了简化数据绑定,Windows 窗体让你可将数据源绑定到 BindingSource 组件,然后将控件绑定到 BindingSource。 你可以在简单或复杂绑定方案中使用 BindingSource。 在任一种情况下,BindingSource 均充当数据源和绑定控件的中介,提供更改通知货币管理和其他服务 

几乎每个商业应用程序都使用读取自一种类型或另一种类型的数据源的信息,方法通常是数据绑定。 以下列表显示了几个最常见的利用数据绑定作为数据表示和操作方法的方案。

方案说明
正在报告报表为你提供了一种灵活的方式来显示和汇总打印出的文档中的数据。 一种常见的做法是:创建一个将数据源的选定内容打印到屏幕或打印机的报表。 常见的报表包括列表、发票和摘要。 将项格式化成列表的列,在每个列表项下组织子项,但你应选择最适合数据的布局。
数据输入输入大量相关数据或提示用户输入信息的常用方法是使用数据输入表单。 用户可以使用文本框、选项按钮、下拉列表和复选框来输入信息或选择选项。 然后提交信息并将其存储在数据库中,数据库结构基于所输入的信息。
大纲/细节关系大纲/细节应用程序是查看相关数据的一种格式。 具体来说,在经典业务示例中,有两个具有连接关系的数据表,“顾客”表和“订单”表之间存在联系客户和对应订单的关系。 有关使用两个 Windows 窗体 DataGridView 控件创建大纲/细节应用程序的详细信息,请参阅如何:使用两个 Windows 窗体 DataGridView 控件创建一个主/从窗体
查找表另一个常见的数据表示/操作方案是表查找。 通常情况下,作为较大数据显示的一部分,ComboBox 控件用于显示和操作数据。 关键在于 ComboBox 控件中显示的数据与写入数据库中的数据不同。 例如,如果你有一个显示杂货店中的物料的 ComboBox 控件,你可能想要查看产品名称(面包、牛奶、鸡蛋)。 但是,为了便于在数据库中检索信息或使数据库标准化,你可能会将给定订单特定项的信息存储为物料编号(#501、#603 等等)。 因此,你窗体上的 ComboBox 控件中的杂货物料“友好名称”和存在于订单中的物料编号间有着隐式联系。 这就是表查找的实质。 有关详细信息,请参阅如何:使用 Windows 窗体 BindingSource 组件创建查找表

结束语

Winform就暂时先到这里吧,后面如果有需要再仔细研究。接下来要赶紧去学WPF了,毕竟Winform已经是淘汰的技术了。诸位一起加油!!!能看到这里的都是对Winform有着极大的需求和努力的,前途路远,诸公加油!!!

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值