WPF之Label控件详解
文章目录
- 1. 引言
- 2. Label控件基础
- 2.1 类继承结构
- 2.2 Label类定义
- 3. Label控件的核心属性
- 3.1 Content属性
- 3.2 Target属性
- 3.3 其他常用属性
- 4. 标签样式与模板自定义
- 4.1 简单样式设置
- 4.2 使用Style对象
- 4.3 触发器使用
- 4.4 使用ControlTemplate完全自定义
- 5. Label与表单控件交互
- 5.1 基本关联
- 5.2 使用访问键
- 5.3 代码实现Label与控件关联
- 6. Label的高级用法
- 6.1 动态内容与绑定
- 6.2 使用ContentStringFormat格式化显示
- 6.3 多语言支持
- 6.4 创建自定义Label控件
- 6.5 Label中使用HTML样式的富文本
- 7. Label控件的事件处理
- 7.1 鼠标事件
- 7.2 创建可点击标签
- 7.3 使用Command绑定
- 8. Label的辅助功能与可访问性
- 8.1 基本可访问性考虑
- 8.2 使用Label提高表单可访问性
- 8.3 屏幕阅读器优化(Win+Ctrl+Enter快捷键进入讲述人模式)
- 9. 性能和最佳实践
- 9.1 Label性能优化
- 9.2 Label使用的最佳实践
- 9.3 Label与TextBlock选择
- 10. 总结
- 学习资源
可以根据Github拉取示例程序运行
GitHub程序演示地址(点击直达)
也可以在本文资源中下载
1. 引言
在WPF应用程序开发中,Label控件是最基础的UI元素之一,用于显示文本和其他内容。作为内容展示的基本组件,Label控件不仅提供了简单的文本显示功能,还能通过丰富的自定义选项创建出各种视觉效果。本文将深入解析WPF中Label控件的特性、用法以及高级应用,帮助开发者全面理解并充分利用这一基础控件。
与其他UI框架中的标签控件相比,WPF的Label控件具有更强的灵活性和更丰富的功能。通过XAML声明式编程和WPF强大的样式系统,Label可以实现从简单文本展示到复杂内容呈现的各种需求。
本文将从Label控件的基础属性开始,逐步深入到样式定制、内容设置、布局控制以及与其他控件的交互等方面,为读者提供全面的Label控件使用指南。
2. Label控件基础
2.1 类继承结构
Label控件继承自ContentControl,可以包含任何类型的内容。在类继承层次上,Label的位置如下:
2.2 Label类定义
在.NET中,Label类的基本定义如下:
public class Label : ContentControl
{// 构造函数public Label();// 依赖属性public static readonly DependencyProperty TargetProperty; // 定义标签关联的目标控件// 属性public UIElement Target { get; set; } // 获取或设置标签关联的目标控件,通常用于访问键功能// 方法protected override void OnInitialized(EventArgs e); // 初始化时调用protected override AutomationPeer OnCreateAutomationPeer(); // 创建自动化对等体用于辅助功能// 其他成员...
}
3. Label控件的核心属性
3.1 Content属性
由于Label继承自ContentControl,它拥有Content属性,可以设置为任何对象,包括字符串、图像、面板等:
<!-- 简单文本标签 -->
<Label Content="用户名:" /><!-- 复杂内容标签 -->
<Label><StackPanel Orientation="Horizontal"><Image Source="/Images/user_icon.png" Width="16" Height="16" Margin="0,0,5,0"/><TextBlock Text="用户名:"/></StackPanel>
</Label>
在C#代码中设置:
// 文本内容
myLabel.Content = "用户名:";// 复杂内容
StackPanel panel = new StackPanel { Orientation = Orientation.Horizontal }; // 创建水平方向的StackPanel作为标签内容容器
panel.Children.Add(new Image
{ Source = new BitmapImage(new Uri("/Images/user_icon.png", UriKind.Relative)), // 设置图像源(相对路径)Width = 16, // 设置图像宽度为16像素Height = 16, // 设置图像高度为16像素Margin = new Thickness(0, 0, 5, 0) // 设置图像右侧边距为5像素,使图像与文本有间隔
});
panel.Children.Add(new TextBlock { Text = "用户名:" }); // 添加文本块作为标签的文字部分
myLabel.Content = panel; // 将整个面板设置为标签的内容
3.2 Target属性
Target属性是Label特有的,用于将标签与其他控件关联起来。当标签中定义了访问键(使用下划线_字符),并且设置了Target属性,按下Alt+访问键会将焦点移动到目标控件:
<Label Content="_用户名:" Target="{Binding ElementName=txtUsername}" />
<TextBox x:Name="txtUsername" />
// 在代码中设置Target
Label usernameLabel = new Label();
usernameLabel.Content = "_u用户名:"; // 下划线表示'u'是访问键
usernameLabel.Target = txtUsername; // 设置目标为用户名文本框
Target属性使Label成为一个可以通过键盘快速访问关联控件的工具,这对于提高表单的可访问性和用户体验非常重要。
3.3 其他常用属性
除了上述特有属性外,Label还继承了许多来自父类的重要属性:
属性名 | 描述 | 示例 |
---|---|---|
Background | 设置标签背景 | <Label Background="LightBlue" /> |
Foreground | 设置标签前景(通常是文本颜色) | <Label Foreground="Navy" /> |
FontSize | 设置标签文本大小 | <Label FontSize="14" /> |
FontWeight | 设置文本粗细 | <Label FontWeight="Bold" /> |
FontFamily | 设置字体 | <Label FontFamily="Segoe UI" /> |
Padding | 设置标签内容的内边距 | <Label Padding="10,5" /> |
Margin | 设置标签的外边距 | <Label Margin="5" /> |
HorizontalAlignment | 设置标签在容器中的水平对齐方式 | <Label HorizontalAlignment="Center" /> |
VerticalAlignment | 设置标签在容器中的垂直对齐方式 | <Label VerticalAlignment="Center" /> |
HorizontalContentAlignment | 设置标签内容的水平对齐方式 | <Label HorizontalContentAlignment="Right" /> |
VerticalContentAlignment | 设置标签内容的垂直对齐方式 | <Label VerticalContentAlignment="Top" /> |
Width/Height | 设置标签的宽度/高度 | <Label Width="100" Height="30" /> |
IsEnabled | 设置标签是否启用 | <Label IsEnabled="False" /> |
Visibility | 设置标签的可见性 | <Label Visibility="Collapsed" /> |
4. 标签样式与模板自定义
WPF强大的样式系统允许我们从简单到复杂地自定义Label的外观。
4.1 简单样式设置
最基本的样式设置可以直接通过设置标签属性完成:
<Label Content="样式化标签" Background="LightYellow" Foreground="DarkGreen"FontWeight="Bold"FontStyle="Italic"Padding="10,5"BorderBrush="DarkGreen"BorderThickness="1" />
4.2 使用Style对象
更系统的方式是创建Style对象:
<Window.Resources><Style x:Key="GreenLabel" TargetType="Label"><Setter Property="Background" Value="LightYellow" /><Setter Property="Foreground" Value="DarkGreen" /><Setter Property="FontWeight" Value="Bold" /><Setter Property="Padding" Value="10,5" /><Setter Property="BorderBrush" Value="DarkGreen" /><Setter Property="BorderThickness" Value="1" /></Style>
</Window.Resources><Label Content="样式化标签" Style="{StaticResource GreenLabel}" />
在C#中动态应用样式:
Style greenLabelStyle = (Style)FindResource("GreenLabel"); // 从资源字典中查找命名为"GreenLabel"的样式
myLabel.Style = greenLabelStyle; // 将样式应用到标签控件
4.3 触发器使用
触发器允许标签在不同状态下有不同的外观:
<Style x:Key="AnimatedLabel" TargetType="Label"><Setter Property="Background" Value="LightYellow" /><Setter Property="Foreground" Value="DarkGreen" /><Setter Property="FontWeight" Value="Normal" /><Setter Property="Padding" Value="10,5" /><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="LightGreen" /><Setter Property="Foreground" Value="DarkBlue" /><Setter Property="FontWeight" Value="Bold" /></Trigger><Trigger Property="IsEnabled" Value="False"><Setter Property="Opacity" Value="0.5" /><Setter Property="Foreground" Value="Gray" /></Trigger></Style.Triggers>
</Style>
4.4 使用ControlTemplate完全自定义
要彻底改变标签的外观,我们需要使用ControlTemplate:
<Style x:Key="FancyLabel" TargetType="Label"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Label"><Border CornerRadius="5" BorderThickness="1" BorderBrush="#CCCCCC"Background="{TemplateBinding Background}"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Border Grid.Row="0" Background="#E0E0E0" Padding="5,2"><TextBlock Text="{TemplateBinding Tag}" FontSize="10" Foreground="Gray"/></Border><ContentPresenter Grid.Row="1" Margin="{TemplateBinding Padding}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="BorderBrush" Value="#999999"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>
上面的代码创建了一个带有标题栏的花式标签模板,标题内容来自Tag属性,主要内容使用ContentPresenter显示。
使用这个模板的标签示例:
<Label Content="详细信息" Tag="信息" Style="{StaticResource FancyLabel}" Background="White"Padding="10,5" />
5. Label与表单控件交互
Label控件最常见的应用场景是与表单控件配合使用,例如TextBox、ComboBox等。
5.1 基本关联
最简单的关联方式是通过布局来实现视觉上的关联:
<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Label Grid.Row="0" Grid.Column="0" Content="用户名:"/><TextBox Grid.Row="0" Grid.Column="1" Margin="5"/><Label Grid.Row="1" Grid.Column="0" Content="密码:"/><PasswordBox Grid.Row="1" Grid.Column="1" Margin="5"/><Label Grid.Row="2" Grid.Column="0" Content="部门:"/><ComboBox Grid.Row="2" Grid.Column="1" Margin="5"/>
</Grid>
5.2 使用访问键
通过Target属性和访问键,可以使用键盘快捷键直接激活相关控件:
<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Label Grid.Row="0" Grid.Column="0" Content="_U用户名:" Target="{Binding ElementName=txtUsername}"/><TextBox x:Name="txtUsername" Grid.Row="0" Grid.Column="1" Margin="5"/><Label Grid.Row="1" Grid.Column="0" Content="_P密码:" Target="{Binding ElementName=txtPassword}"/><PasswordBox x:Name="txtPassword" Grid.Row="1" Grid.Column="1" Margin="5"/><Label Grid.Row="2" Grid.Column="0" Content="_D部门:" Target="{Binding ElementName=cboDepartment}"/><ComboBox x:Name="cboDepartment" Grid.Row="2" Grid.Column="1" Margin="5"/>
</Grid>
在上面的示例中,用户可以(或Alt+U)直接将焦点移动到用户名文本框,(或Alt+P)移动到密码框,(或Alt+D)移动到部门下拉框。
5.3 代码实现Label与控件关联
在代码中通过C#实现Label与控件的关联:
private void InitializeForm()
{// 创建用户名标签和文本框Label lblUsername = new Label();lblUsername.Content = "_U用户名:"; // 下划线定义访问键TextBox txtUsername = new TextBox();lblUsername.Target = txtUsername; // 设置标签目标为文本框// 创建密码标签和密码框Label lblPassword = new Label();lblPassword.Content = "_P密码:";PasswordBox txtPassword = new PasswordBox();lblPassword.Target = txtPassword;// 将控件添加到布局容器Grid grid = new Grid();// 设置列定义grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });// 设置行定义grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });// 添加用户名控件到GridGrid.SetRow(lblUsername, 0);Grid.SetColumn(lblUsername, 0);grid.Children.Add(lblUsername);Grid.SetRow(txtUsername, 0);Grid.SetColumn(txtUsername, 1);txtUsername.Margin = new Thickness(5);grid.Children.Add(txtUsername);// 添加密码控件到GridGrid.SetRow(lblPassword, 1);Grid.SetColumn(lblPassword, 0);grid.Children.Add(lblPassword);Grid.SetRow(txtPassword, 1);Grid.SetColumn(txtPassword, 1);txtPassword.Margin = new Thickness(5);grid.Children.Add(txtPassword);// 将Grid添加到窗口内容this.Content = grid;
}
6. Label的高级用法
6.1 动态内容与绑定
Label控件可以通过数据绑定动态显示内容:
<Label Content="{Binding UserName}" ContentStringFormat="用户名: {0}"/>
在ViewModel中:
public class UserViewModel : INotifyPropertyChanged
{private string _userName;public string UserName{get { return _userName; }set {if (_userName != value){_userName = value;OnPropertyChanged(nameof(UserName)); // 通知UI该属性已更改}}}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); // 触发属性更改事件}
}
6.2 使用ContentStringFormat格式化显示
ContentStringFormat属性允许对显示内容进行格式化:
<Label Content="{Binding Price}" ContentStringFormat="价格: {0:C}"/>
这将使Price值按货币格式显示,例如"价格: ¥123.45"。
6.3 多语言支持
使用资源文件和绑定可以实现Label内容的多语言支持:
<Label Content="{Binding Source={StaticResource Resources}, Path=UsernameLabel}" />
在资源文件中定义不同语言的标签内容:
<!-- 中文资源文件 -->
<system:String x:Key="UsernameLabel">用户名:</system:String><!-- 英文资源文件 -->
<system:String x:Key="UsernameLabel">Username:</system:String>
6.4 创建自定义Label控件
为特定需求创建自定义Label控件:
public class RequiredFieldLabel : Label
{static RequiredFieldLabel(){// 覆盖默认样式DefaultStyleKeyProperty.OverrideMetadata(typeof(RequiredFieldLabel),new FrameworkPropertyMetadata(typeof(RequiredFieldLabel))); // 设置默认样式键类型为RequiredFieldLabel}public RequiredFieldLabel(){// 在构造函数中初始化this.Loaded += RequiredFieldLabel_Loaded; // 注册Loaded事件处理程序}private void RequiredFieldLabel_Loaded(object sender, RoutedEventArgs e){// 创建一个StackPanel来布局内容StackPanel panel = new StackPanel { Orientation = Orientation.Horizontal // 设置为水平方向};// 保存原始内容object originalContent = this.Content; // 保存标签原有内容this.Content = null; // 清除内容,将用新的面板替代// 添加原始内容到面板if (originalContent != null){ContentPresenter cp = new ContentPresenter{Content = originalContent // 设置内容为标签原有内容};panel.Children.Add(cp); // 添加到面板中}// 添加红色星号TextBlock asterisk = new TextBlock{Text = " *", // 星号前有一个空格Foreground = Brushes.Red, // 设置为红色FontWeight = FontWeights.Bold, // 设置为粗体VerticalAlignment = VerticalAlignment.Top // 设置垂直对齐为顶部};panel.Children.Add(asterisk); // 添加到面板中// 将新的面板设置为Label的内容this.Content = panel; // 将整个面板设置为标签的新内容}
}
在XAML中使用自定义Label:
<local:RequiredFieldLabel Content="用户名"/>
然后在Generic.xaml中定义样式:
<Style TargetType="{x:Type local:RequiredFieldLabel}"><Setter Property="Foreground" Value="Navy"/><Setter Property="FontWeight" Value="Bold"/>
</Style>
6.5 Label中使用HTML样式的富文本
虽然Label不直接支持HTML,但可以使用TextBlock配合Run和其他内联元素来实现类似富文本效果:
<Label><TextBlock><Run Text="普通文本" /><Run Text="粗体文本" FontWeight="Bold" /><Run Text="颜色文本" Foreground="Red" /><Hyperlink NavigateUri="https://www.example.com" RequestNavigate="Hyperlink_RequestNavigate">点击链接</Hyperlink></TextBlock>
</Label>
对应的事件处理代码:
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{// 使用默认浏览器打开链接Process.Start(new ProcessStartInfo{FileName = e.Uri.AbsoluteUri,UseShellExecute = true});e.Handled = true; // 标记事件已处理
}
7. Label控件的事件处理
虽然Label主要是显示控件,但它仍然继承了许多交互事件。
7.1 鼠标事件
Label支持标准的鼠标事件,可用于创建交互式标签:
<Label Content="点击查看详情" MouseLeftButtonDown="Label_MouseLeftButtonDown"Cursor="Hand"Foreground="Blue"TextDecorations="Underline"/>
private void Label_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{// 显示详细信息窗口或执行其他操作MessageBox.Show("这里是详细信息内容");e.Handled = true; // 标记事件已处理,防止事件继续传播
}
7.2 创建可点击标签
结合样式和事件处理,可以创建类似超链接的可点击标签:
<Style x:Key="HyperlinkLabel" TargetType="Label"><Setter Property="Foreground" Value="Blue"/><Setter Property="Cursor" Value="Hand"/><Setter Property="TextDecorations" Value="Underline"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Foreground" Value="DarkBlue"/></Trigger></Style.Triggers>
</Style><Label Content="查看更多..." Style="{StaticResource HyperlinkLabel}" MouseLeftButtonDown="ViewMoreLabel_Click"/>
private void ViewMoreLabel_Click(object sender, MouseButtonEventArgs e)
{// 处理点击事件// 例如导航到新页面或打开对话框NavigationService.Navigate(new Uri("DetailsPage.xaml", UriKind.Relative));
}
7.3 使用Command绑定
在MVVM模式中,可以结合InputBindings使Label支持命令绑定:
<Label Content="执行操作" Cursor="Hand"><Label.InputBindings><MouseBinding MouseAction="LeftClick" Command="{Binding ExecuteCommand}"/></Label.InputBindings>
</Label>
在ViewModel中定义命令:
public class MainViewModel
{private ICommand _executeCommand;public ICommand ExecuteCommand{get{return _executeCommand ?? (_executeCommand = new RelayCommand(param => ExecuteAction(),param => CanExecuteAction()));}}private bool CanExecuteAction(){// 判断命令是否可执行的逻辑return true; // 总是可执行}private void ExecuteAction(){// 执行命令的具体逻辑MessageBox.Show("命令已执行");}
}
8. Label的辅助功能与可访问性
8.1 基本可访问性考虑
为提高应用程序的可访问性,使用Label时应注意:
- 确保Label与控件正确关联(使用Target属性)
- 提供有意义的访问键
- 设置适当的AutomationProperties信息
<Label Content="_用户名:" Target="{Binding ElementName=txtUsername}" AutomationProperties.HelpText="输入您的登录用户名"AutomationProperties.Name="用户名标签"/>
8.2 使用Label提高表单可访问性
结合Label的Target和访问键功能,可以大幅提高表单的键盘可访问性。在表单设计中,每个输入控件都应有一个关联的Label:
<StackPanel><Label Content="_名字:" Target="{Binding ElementName=txtFirstName}"/><TextBox x:Name="txtFirstName"/><Label Content="_姓氏:" Target="{Binding ElementName=txtLastName}"/><TextBox x:Name="txtLastName"/><Label Content="_电子邮件:" Target="{Binding ElementName=txtEmail}"/><TextBox x:Name="txtEmail"/><Label Content="_电话号码:" Target="{Binding ElementName=txtPhone}"/><TextBox x:Name="txtPhone"/>
</StackPanel>
8.3 屏幕阅读器优化(Win+Ctrl+Enter快捷键进入讲述人模式)
为了使标签与屏幕阅读器更好地配合,应确保:
- 使用明确的文本描述
- 设置AutomationProperties.LabeledBy属性关联控件与标签
- 在适当情况下设置AccessText属性
<Label x:Name="lblPhone" Content="电话号码:"/>
<TextBox x:Name="txtPhone" AutomationProperties.LabeledBy="{Binding ElementName=lblPhone}"AutomationProperties.HelpText="请输入您的联系电话,格式为:XXX-XXXX-XXXX"/>
9. 性能和最佳实践
9.1 Label性能优化
- 避免过度使用Label:当只需要显示静态文本时,考虑使用TextBlock代替Label,因为TextBlock更轻量。
- 适当缓存:对于复杂内容的Label,考虑使用BitmapCache提高性能。
<Label Content="复杂内容标签" FontSize="18"><Label.CacheMode><BitmapCache /></Label.CacheMode>
</Label>
9.2 Label使用的最佳实践
-
选择合适的控件:
- 用于表单标签时,使用Label并设置Target属性
- 仅显示文本时,优先考虑TextBlock
- 需要富文本时,考虑使用TextBlock配合多个Run或其他内联元素
-
恰当设置访问键:选择有意义且容易记住的字符作为访问键。
-
保持一致的样式:在整个应用程序中保持标签样式的一致性。
-
布局考虑:
- 在表单中,使标签与关联控件的对齐方式保持一致
- 对于右对齐的标签,设置
HorizontalContentAlignment="Right"
- 表单内的所有标签宽度应保持一致
-
多语言支持:使用资源文件和绑定,避免硬编码标签内容。
9.3 Label与TextBlock选择
Label和TextBlock是WPF中两个可以显示文本的控件,但它们有明显区别:
特性 | Label | TextBlock |
---|---|---|
继承层次 | ContentControl | FrameworkElement |
内容类型 | 任意内容 | 仅文本和内联元素 |
Target属性 | 支持 | 不支持 |
访问键 | 支持 | 不支持 |
模板支持 | 完全支持 | 有限支持 |
控件模型 | 完整控件 | 轻量级框架元素 |
性能 | 较重 | 轻量 |
适用场景 | 表单标签、需要模板化的文本 | 静态文本显示、富文本显示 |
选择原则:
- 如果需要关联到另一个控件(使用访问键),选择Label
- 如果只是显示文本且不需要控件特性,选择TextBlock
- 如果需要丰富的文本格式化,选择TextBlock配合内联元素
10. 总结
WPF中的Label控件是一个功能丰富的文本显示组件,它不仅提供基本的文本显示功能,还支持复杂内容、控件关联和各种样式定制。通过Label的Target属性和访问键功能,可以显著提高应用程序的可访问性和用户体验。
Label控件的主要特点和优势包括:
- 作为ContentControl,可以容纳任何类型的内容
- 通过Target属性和访问键提供键盘导航支持
- 强大的样式和模板自定义能力
- 与其他表单控件的良好整合
通过本文的详细介绍,我们了解了Label控件的核心属性、样式自定义、与表单控件的交互、高级用法以及性能优化等方面。掌握这些知识,可以帮助开发者在WPF应用程序中更有效地使用Label控件,创建出更友好、更易用的用户界面。
学习资源
以下是一些深入学习WPF Label控件的优质资源:
- 微软官方文档:Label类
- WPF控件深入详解系列 - MSDN
- WPF UI设计最佳实践指南
- WPF示例代码库
- WPF数据绑定深入解析
- Stack Overflow上的WPF标签问题集
通过系统学习和不断实践,你将能够充分利用WPF Label控件的强大功能,创建出更加直观、易用的用户界面。
相关文章:
WPF之Label控件详解
文章目录 1. 引言2. Label控件基础2.1 类继承结构2.2 Label类定义 3. Label控件的核心属性3.1 Content属性3.2 Target属性3.3 其他常用属性 4. 标签样式与模板自定义4.1 简单样式设置4.2 使用Style对象4.3 触发器使用4.4 使用ControlTemplate完全自定义 5. Label与表单控件交互…...
STM32 HAL库实现USB虚拟串口
1. 引言 在嵌入式系统开发中,USB 虚拟串口是一种非常实用的功能。它允许 STM32 微控制器通过 USB 接口与计算机进行通信,就像使用传统的串口一样。这种方式不仅简化了硬件设计,还提高了通信的灵活性和稳定性。STM32F407 系列微控制器具有强大…...
第二阶段:基础加强阶段总体介绍
Java语法的学习笔记 下面放复习的文档链接,如果有需要可以前往下载获取,这个仓库还有关于mysql、hadoop、python等的复习部分,并且每个文档有着对应的代码部分。文章作为复习使用,更多代码内容见链接如下: https://gitee.com/zha…...
Callable Future 实现多线程按照顺序上传文件
/** * 异步上传 BiopsyFlow 中的所有视频和音频文件到暂存服务器 */ private List<String> uploadBiopsyFlowFiles(BiopsyFlow biopsyFlow, SyncFile SyncFile) { List<String> fileBase64List syncFile.getFileBase64List(); if (CollectionUtils.is…...
leetcode283-移动零
leetcode 283 思路 本题是通过把数组中所有不为0的数字前置,实现把所有的0后置的效果 双指针法 slow 充当指针,记录当前零应该被移到的位置。而 i 用来遍历整个数组,检查每个元素。如果当前元素不为零,就将其与 slow 位置上的…...
【dify+docker安装教程】
目录 一、dify安装包下载 二、运行环境配置 1、下载docker 2、安装 2.1 新建文件夹 2.2 安装 2.3 命令安装 3.下载完成后需要重启电脑,注意保存文档!!注意保存!!注意!!(血的教…...
GPU虚拟化实现(五)
GPU虚拟化实现(五) 章节回顾初步介绍详细介绍核心数据结构核心功能和运作机制初始化显存分配显存释放显存溢出检查显存类型检查查看分配信息代码执行流程假设例子总结章节回顾 在上一章,简单介绍了项目拦截cuda函数的流程,其本质上与拦截nvml函数的流程是一致的,都是首先…...
C++——入门基础
文章目录 一、前言二、C的发展历史2.1 C的诞生2.2 C的重要性 三、C的应用3.1第一个C程序3.2 C版3.2 C版3.3 C版与C版的区分 3.2 namespace关键字3.2.1 namespace的意义3.2.2C中域的分类3.2.3 namespace的定义3.2.4 namespace的实质3.2.5 namespace的嵌套 3.3 作用域运算符 &…...
AT2401C与RFX2401C问题处理资料
1、AT2401C 可以 PIN 对 PIN 替代 RFX2401C 吗? 答:AT2401C 可以 PIN 对 PIN 替换 RFX2401C;同时 CB2401 也可以 PIN 对 PIN 替换 RFX2401C;我们主要推 AT2401C 这款芯片,如果客户产 品需要过认证或者应用于音频产品建…...
微信小程序连续多个特殊字符自动换行解决方法
效果图 .wxml <view class"container"><text>没转换{{text}}</text><view style"height: 60rpx;" /><text>转换后{{convert}}</text> </view>.js Page({data: {text:!!!&am…...
【Linux实践系列】:进程间通信:万字详解命名管道实现通信
🔥 本文专栏:Linux Linux实践项目 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 与其等待完美的风,不如学会在逆风中调整帆的角度——所有伟大航程都始于此刻出发的勇气 ★★★ 本文前置知…...
【TS入门笔记4---装饰器】
TS入门笔记4 TypeScript---装饰器一、装饰器基础1. 定义与作用:装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问符、属性或参数上,用来修改类的行为。在 TypeScript 里,装饰器本质上是一个函数,它接收不…...
大学之大:韩国科学技术研究院2025.4.28
韩国科学技术研究院(KAIST)作为韩国理工科教育与科研的旗舰机构,其发展历程深刻反映了韩国从工业化到科技强国的转型轨迹。以下从历史沿革、学科优势、教学特色、科研创新、教育规模、资源投入及未来战略等维度展开全面分析: 一、…...
【QT】QT控制硬件
QT控制硬件 1.上位机程序开发2.具体例子控制led灯3. linux中的函数跟QT类里面的函数同名,发生冲突4.示例代码 1.上位机程序开发 QT做一个上位机程序,控制底层的硬件设备(下位机) 总结: 在构造函数里面去初始化,打开硬件驱动在析…...
Spring的BeanFactory和FactoryBean的区别
BeanFactory和FactoryBean在Spring框架中扮演着不同的角色,具有不同的功能和用途。 定义与角色 BeanFactory:BeanFactory是Spring IoC容器的核心接口,用于管理和维护Bean的定义、创建和生命周期。它是Spring IoC容器的基础&…...
【JavaScript】if语句
JS中的程序是从上到下一行一行执行的。 通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行语句。 语句的分类: 1、条件判断语句 2、条件分支语句 3、循环语句 条件判断语句:使用条件判断语句可以在执行某个语句之前进…...
PostgreSQL oracle_fdw 扩展解析
PostgreSQL oracle_fdw 扩展解析 oracle_fdw 是 PostgreSQL 的一个外部数据包装器(Foreign Data Wrapper)扩展,允许 PostgreSQL 直接连接和操作 Oracle 数据库。以下是全面详细的使用指南: 一、安装与配置 1. 前置要求 Oracle 客户端库:必…...
从信息传输到智能互动,融云的全球智能通信云服务进化
4 月 24 日-25 日,GTC2025 全球流量大会在深圳福田会展中心举办,融云携全球智能通信云解决方案亮相。 在大会首日的开幕式峰会上,融云高级研发总监李宏博受邀分享《从信息传输到智能互动,融云的全球智能通信云服务进化》。 作为连…...
关于https请求丢字符串导致收到报文解密失败问题
加密方法:AES两次URLEncoder 问题现象:服务端收到的报文中少了类似%25这样的字符,导致解密失败 问题分析:用RequestBody接受 也有可能是springboot自动做了一次解码URLDecoder,自己只需要解码一次就好了...
Rust 学习笔记:修复所有权常见错误
Rust 学习笔记:修复所有权常见错误 Rust 学习笔记:修复所有权常见错误错误一:返回栈上的引用错误二:没有足够的权限错误三:别名和可变性错误四:从集合中拷贝一个元素(转移所有权)错误…...
Unity3D引擎框架及用户接口调用方式相关分析及汇总
分析目的 目前外网3D手游绝大部基于Unity3D引擎进行开发,Unity3D引擎属于商业引擎,引擎整理框架的运行机制较为神秘,本文介绍Unity引擎框架、对象组织方式、用户接口与引擎交互方式等原理,通过本文的分析和介绍可了解Unity3D框架中大致执行原理。 实现原理 Unity引擎作为…...
喷泉码在物联网场景下的案例分析
在物联网复杂场景下,无线传感器网络作为信息感知前端,面临能量受限、信道不稳定、多跳传输可靠性差等难题,严重制约物联网系统运行效能。传统基于反馈重传的通信机制在无线传感器网络中难以为继。其 ACK 确认操作频繁,大幅增加能耗,且在动态网络拓扑中,反馈易丢失,致使数…...
OpenCV 图形API(69)图像与通道拼接函数------将一个 GMat 类型的对象转换为另一个具有不同深度GMat对象函数convertTo()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将一个矩阵转换为另一种数据深度,并可选择进行缩放。 该方法将源像素值转换为目标数据深度。最终应用 saturate_cast<> 以避免…...
考研系列-计算机组成原理第七章、输入/输出系统
一、I/O接口 1.I/O接口概念 现在的I/O接口有些集成在南桥芯片上...
使用vue3 脚手架创建项目
1.创建项目 并 运行 1.1 创建项目 vue create abcd 1.2 运行 创建好项目后,命令行会提示你运行项目 npm run serve 2.介绍各个目录 node_modules : 项目依赖包,其中包括很多基础依赖,自己也可以根据需要安装其他依赖 assets文件夹&a…...
云服务器被黑客攻击应急响应与加固指南(上)
一、入侵检测与应急处理 1. 异常行为检测 # 查看异常登录记录 sudo lastb | awk {print $3} | sort | uniq -c | sort -nr sudo grep "Failed password" /var/log/auth.log | awk {print $11} | sort | uniq -c# 检查可疑进程 ps auxf | grep -E (curl|wget|bash|s…...
联合体union的特殊之处
一个联合体union的长度等于其内部长度最大的成员的长度。 union的所有成员共享同一块内存空间,可以利用这个特性读取数据的字节存储方式。 #include <stdio.h>int check_endian() {union {short s; // 2 字节(short)char c[2]…...
Spring系列五:手动实现Spring底层机制 第三部分
💗实现任务阶段5 🍚bean后置处理器实现 bean后置处理器实现 思路:先完成原生Spring 使用Bean后置处理器的案例, 然后实现自己的bean后置处理器 bean的生命周期~传送门 在idea中 shortcuts: shiftshift , 输入 InitializingBean, 搜索. 在zzw-spring…...
AGV、AMR机器人控制器x86/RK3588/NV各有什么优劣势?
以下是关于AGV/AMR机器人控制器解决方案中x86、RK(瑞芯微)、NV(英伟达)平台优劣势的综合分析: 一、核心性能对比 平台优势局限性适用场景x861. 多核高频CPU支持复杂算法运算,适合大规模路径规划及多机…...
[ACTF2020 新生赛]Include [ACTF2020 新生赛]Exec
[ACTF2020 新生赛]Include 因为前端过滤的太多了 所以直接使用 日志包含 搞 包含这个 /var/log/nginx/access.log [ACTF2020 新生赛]Include蚁剑连接 翻看 flag{1ce7a81e-0339-44ef-a398-a7784d3efe37} [ACTF2020 新生赛]Exec [ACTF2020 新生赛]Exec 127.0.0.1 |echo <?…...
23种设计模式 -- 工厂模式
Java 工厂模式示例代码 下面我将展示三种常见的工厂模式实现:简单工厂模式、工厂方法模式和抽象工厂模式。 1. 简单工厂模式 java // 产品接口 interface Shape {void draw(); }// 具体产品类 class Circle implements Shape {Overridepublic void draw() {System…...
【25软考网工】第四章(2)WLAN通信技术、WLAN频谱与信道
目录 一、WLAN通信技术 1. 扩展频谱通信 1)扩频通信种类 2)技术关系 2. 应用案例 1)例题:扩频通信概念判定 2)例题:跳频扩频技术描述 3)例题:扩频通信技术标准 3.知识小结 二、WLAN频谱与信道 1. WLAN网络分…...
MetaEditor - 自动交易和技术指标编辑器
功能特点 代码编辑功能:支持多种编程语言,如 MQL4 和 MQL5,方便交易者根据自己的需求编写自动交易策略和技术指标。它提供了代码高亮、自动缩进、语法检查等功能,有助于提高代码编写的效率和准确性。调试与测试工具:配…...
关于华为云OneAccess登录认证过程介绍
这里主要介绍的是OAuth2认证的一个流程,分享一下实际开发过程中的实现逻辑 1、后端先根据接口文档的细节内容,然后拼接好url并且以String的类型返回给前端 2、此时前端会访问本连接,然后就会跳转到第三方页面,用户进行登录后&am…...
Spring - 简单实现一个 Spring 应用
一、为什么需要学习Spring框架? 1.企业级开发标配 超过60%的Java项目都使用Spring生态(数据来源:JetBrains开发者报告)。 2.简化复杂问题 通过IoC和DI,告别new关键字满天飞的代码。 3.职业竞争力 几乎所有Java岗…...
数据展示功能界面设计与实现及终端控制界面思路(17)
文章目录 一、本章说明二、传感数据展示功能实现2.1 实现目标2.2 具体实现2.2.1 需要在.pro 文件添加2.2.2 mainwindow.h 头文件2.2.3 mainwindow.cpp 文件2.2.4 实现界面展示三、项目源码文件四、终端节点控制五、Qt打包EXE一、本章说明 注:本节为【基于STM的环境监测系统(…...
opendds编译开发(c#封装)
opendds是对DDS协议的开源实现,具体可以查阅官网。 我使用的是源码编译开发,博文只针对windows平台。 环境准备 环境安装 1.visual studio 2022,我是企业版,安装需要选择c 2.Per下载安装,下载链接:https://strawberryperl.com…...
电子监管码预检剔除装置提示盒尺寸过短
问题:电子监管码预检剔除装置提示盒尺寸过短 现象:自动线监控程序报警提示“盒尺寸过短”。 原因:分盒设备拨盒的力度和距离、盒子在传送带的角度或传送带速度有所变化都会导致自动线出现“盒尺寸过短” 解决方法:根据传送带的速…...
【C++11特性】Lambda表达式(匿名函数)
一、函数对象 在C中,我们把所有能当作函数使用的对象当作函数对象。 一般来说,如果我们列出一个对象,而它的后面又跟有由花括号包裹的参数列表,就像fun(arg1, arg2, …),这个对象就被称为函数对象。函数对象大致可分为…...
【北京】昌平区某附小v3700存储双控故障维修案例
2025年4月22日,接到一位通过网络找到我们的北京老师求助,反馈该学校一台V3700存储的磁盘分区无法正常读取了,老师在机房检查时发现存储后面2个控制器均亮警告灯。急需修复该设备读取里面资料用于周末运动会所需。于是在网上找到我们协助进行排…...
汤晓鸥:计算机视觉的开拓者与AI产业化的先行者
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 汤晓鸥:计算机视觉的开拓者与AI产业化的先行者 一、学术与创业之路 1. 从…...
MATLAB实现神经网络的OCR识别
使用说明: 运行要求: MATLAB R2020b 或更新版本已安装 Deep Learning Toolbox推荐使用GPU加速(训练时在代码开头添加 gpuDevice(1)) 代码特点: 使用MATLAB自带的MNIST手写数字数据集包含数据可视化、网络架构…...
车载软件架构 --- AUTOSAR的方法论
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
Java 的创新与变革之路:从 JDK 7 到 JDK 23
Java 作为一种广泛应用的编程语言,其发展历程与 JDK(Java Development Kit)的演进紧密相连。自 JDK 7 起,Java 语言不断引入重大特性,持续重塑开发格局,推动性能、功能和开发体验的提升。本文将深入剖析 JD…...
LangChain、LlamaIndex、MCP、Spring AI、Ollama 和 DeepSeek 的定义、关系及典型架构设计
以下是 LangChain、LlamaIndex、MCP、Spring AI、Ollama 和 DeepSeek 的定义、关系及典型架构设计解析: 一、核心组件定义与功能 1. LangChain 定位:构建复杂 大语言模型(LLM)应用的通用框架。功能: 支持链式调用&am…...
Docker安装的mysql限制ip访问
1.问题背景 docker安装了mysql服务,服务器为Redhat9,我们希望通过防火墙规则直接限制访问的来源ip,只允许特定ip进行访问,其余ip需要被禁止。 2.排查过程 1.首先尝试了通过firewalld方式添加对应的防火墙规则, sud…...
怎么样才能在idea中写入spark程序
一、准备环境 1.安装Scala插件 专业版IDEA自带Scala插件,社区版需手动安装 确保插件版本与IDEA版本匹配 2.选择用哪个构建工具 sbt:适用于依赖管理简单、快速迭代的项目,需提前安装sbt工具24。 Maven:适合熟悉Java生态…...
MySQL的数据类型
目录 数据类型分类 数值类型 tinyint bit 编辑 小数(float) 小数(decimal) 字符串类型 char varchar 日期和时间类型 String类型 enum set find_ in_ set函数 我们今天来学习MySQL的数据分类。 数据类型分类 MySQL的字符型就是相当于字符串类型,所…...
Vue 中局部指令(directives)的用法详解
在 Vue.js 中,指令是一种特殊的属性,用于在 DOM 元素上绑定特殊行为。除了 Vue 内置的指令(如v-model、v-if),还可以自定义指令来封装可复用的功能。 什么是局部指令? 局部指令是在单个组件中定义和使用的…...
mac 基于Docker安装minio服务器
在 macOS 上基于 Docker 安装 MinIO 是一个高效且灵活的方案,尤其适合本地开发或测试环境。以下是详细的安装与配置步骤,结合了最佳实践和常见问题的解决方案: 一、安装 Docker Desktop 下载安装包 访问 Docker 官网,下载适用于 …...