总览:
按钮 (Buttons)
- Button:基本按钮控件,用户点击时触发操作或事件。
- RepeatButton:类似于 Button,但按住不放时会持续触发点击事件,适合需要重复输入的情况。
数据显示 (Data Display)
- DataGrid:强大的数据表格控件,用于显示和编辑数据的表格形式,支持排序、过滤和分组。
- ListView:用于显示数据列表,支持自定义布局和排序,常用于显示数据集合。
- TreeView:用于显示树形结构的数据,比如文件夹和文件的层次结构。
日期显示和选择 (Date Display and Selection)
- Calendar:显示月份的日历控件,用户可以选择一个或多个日期。
- DatePicker:允许用户从日历中选择日期,通常用于表单输入。
对话框 (Dialog Boxes)
- OpenFileDialog:用于让用户选择一个或多个文件的对话框。
- PrintDialog:用于配置打印设置并发送文档到打印机的对话框。
- SaveFileDialog:让用户选择保存文件路径和文件名的对话框。
数字墨水 (Digital Ink)
- InkCanvas:允许用户通过触控或手写笔在其上绘制和书写的画布控件。
- InkPresenter:用于呈现和处理数字墨水数据,通常与 InkCanvas 一起使用。
文档 (Documents)
- DocumentViewer:用于查看文档(如 XPS 文件)的控件。
- FlowDocumentPageViewer:以分页形式显示文档的控件,适合较长文档的阅读。
- FlowDocumentReader:允许用户以多种布局模式查看文档的控件。
- FlowDocumentScrollViewer:类似于 ScrollViewer,用于滚动查看长文档。
- StickyNoteControl:用于添加和显示粘性便签,通常用于注释文档。
输入 (Input)
- TextBox:用于接受用户文本输入的基本控件。
- RichTextBox:类似于 TextBox,但支持富文本格式(如粗体、斜体等)的输入和编辑。
- PasswordBox:专门用于输入密码的控件,输入内容以掩码字符显示。
布局 (Layout)
- Border:为子元素提供边框的简单控件。
- Canvas:允许子元素自由定位的容器,不受布局规则约束。
- DockPanel:将子元素停靠在容器的边缘,未停靠的元素占据剩余空间。
- Grid:网格布局,子元素根据行和列排列。
- StackPanel:将子元素垂直或水平堆叠排列的容器。
- WrapPanel:将子元素从左到右依次排列,当一行放不下时换行排列。
媒体 (Media)
- Image:用于显示图像的控件。
- MediaElement:用于播放音频和视频内容的控件。
- SoundPlayerAction:允许在响应某些事件时播放声音的控件。
菜单 (Menus)
- ContextMenu:为元素提供右键菜单的控件。
- Menu:提供菜单栏,常用于应用程序的主菜单。
- ToolBar:工具栏控件,通常包含一系列按钮和操作。
导航 (Navigation)
- Frame:用于导航和显示内容的控件,通常与导航结构结合使用。
- Hyperlink:文本链接控件,用户点击后可以导航到指定 URL 或其他内容。
- Page:独立的页面控件,通常在 Frame 或 NavigationWindow 中使用。
- NavigationWindow:支持导航功能的窗口控件,类似于浏览器窗口。
- TabControl:标签页控件,允许在不同选项卡之间切换显示内容。
选择 (Selection)
- CheckBox:允许用户进行二元选择(勾选或未勾选)的控件。
- ComboBox:下拉列表控件,用户可以从中选择一个选项。
- ListBox:类似于 ComboBox,但显示的是完整的选项列表,用户可以选择一个或多个项。
- RadioButton:一组单选按钮,用户在一组中只能选择一个。
- Slider:滑块控件,用户可以通过拖动滑块选择一个范围内的值。
用户信息 (User Information)
- AccessText:用于显示带有加速键(快捷键)的文本的控件。
- Label:用于显示静态文本的简单控件,通常与其他控件结合使用。
- Popup:弹出控件,显示在其他内容之上的临时消息或界面。
- ProgressBar:进度条控件,用于显示任务的完成进度。
- StatusBar:通常用于显示应用程序状态信息的底部条状控件。
- TextBlock:用于显示文本的轻量级控件,适合较小文本块。
- ToolTip:为其他控件提供工具提示的控件,当用户悬停在控件上时显示附加信息。
通用设置
动态调整控件大小:
可以使用 MinHeight
、MaxHeight
、MinWidth
和 MaxWidth
来限制控件的大小,并使用 HorizontalAlignment
和 VerticalAlignment
来控制对齐方式。
<Button Content="调整大小的按钮"
Height="100"
Width="200"
MinHeight="50"
MaxHeight="150"
HorizontalAlignment="Center" />
根据控件内部实际使用空间自由填充:
可以通过设置 Grid
的 Height="Auto"
或 Width="Auto"
,使得控件根据其内容自动调整大小。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="这个控件的高度会根据内容自动调整" />
<Button Grid.Row="1" Content="这个按钮会占用剩余空间" />
</Grid>
字体设置
<TextBlock Text="组合字体样式"
FontWeight="Bold"
FontStyle="Italic"
FontSize="20"
Foreground="Blue"
FontFamily="Times New Roman" />
不同部分使用不同样式:
<TextBlock>
<Run Text="加粗的部分" FontWeight="Bold" />
<Run Text="普通字体" />
<Run Text="斜体部分" FontStyle="Italic" />
</TextBlock>
TextWrapping
控制文本内容是否在控件宽度超出时换行。
NoWrap:不换行,文本会溢出控件。
Wrap:自动换行,当文本超过控件宽度时自动换行。
WrapWithOverflow:换行时允许溢出部分文本。
<TextBlock Text="This is a very long text" TextWrapping="Wrap"/> <!-- 文本超过控件宽度时换行 -->
<TextBox Text="This is another long text" TextWrapping="WrapWithOverflow"/> <!-- 换行但允许溢出 -->
对齐
Margin
用于设置控件与其周围元素之间的间距。
Margin="left,top,right,bottom",也可以简写为一个或两个值。
- 四个值表示四个方向的间距。
- 两个值时,第一个值是左右,第二个是上下。
- 一个值表示四个方向的间距相同。
<Button Content="Click Me" Margin="10"/> <!-- 四个方向都是10px -->
<Button Content="Click Me" Margin="10,20"/> <!-- 左右10px,上下20px -->
<Button Content="Click Me" Margin="5,10,15,20"/> <!-- 分别设置左、上、右、下的边距 -->
HorizontalAlignment
控制整个控件在其父容器中的水平对齐方式(控件本身的位置),适用于所有 UI 元素
Left:控件左对齐。
Center:控件水平居中对齐。
Right:控件右对齐。
Stretch:控件在父容器中水平拉伸填充。
<Button Content="Submit" HorizontalAlignment="Right" Width="100"/> <!-- 按钮在父容器中右对齐 -->
HorizontalContentAlignment
制控件内的内容(如文本、子控件)在水平方向上的对齐方式,常用于如 Button、TextBox、Label 等控件。
可用的和HorizontalAlignment一致,也是那4个
<Button Content="Submit" HorizontalContentAlignment="Center"/> <!-- 按钮内的文本居中 -->
滚动条
HorizontalScrollBarVisibility
控制是否显示水平滚动条,常用于 TextBox、ScrollViewer。
Disabled:禁用水平滚动条,内容超出也不会滚动。
Auto:当内容超出可视区域时自动显示水平滚动条。
Hidden:隐藏水平滚动条,但内容依然可以滚动。
Visible:始终显示水平滚动条,无论内容是否超出
<TextBox HorizontalScrollBarVisibility="Auto" TextWrapping="NoWrap" Width="100" Height="50"/> <!-- 当文本超过宽度时显示滚动条 -->
Button(按钮)
按钮是用户界面中最常见的交互控件之一,用于触发事件或命令。
<Button Content="Click Me" Width="100" Height="50" Click="Button_Click"/>
myButton.IsEnabled = false; // 禁用
myButton.IsEnabled = true; // 启用
<Button Content="Click Me" Visibility="Collapsed"/>
Visibility 属性的可选值有:
- Visible: 控件可见
- Collapsed: 控件不可见,并且不占用布局空间
- Hidden: 控件不可见,但仍占用布局空间
2. TextBox(文本框)
文本框允许用户输入和编辑文本。
<TextBox Width="200" Height="30" Text="Enter text here" />
TextBlock(文本块)
文本块用于显示只读文本。只显示文本,没有交互功能,性能较好
<TextBlock Text="Hello, World!" FontSize="16" FontWeight="Bold" />
Label(标签)
标签用于显示描述性文本,一般用于表单标签。具备为控件指定焦点的功能,并且可以包含更多复杂的内容如按钮,图标等
<Label Content="Name:" />
CheckBox(复选框)
复选框允许用户选择或取消选择一个选项。
<CheckBox Content="Accept Terms and Conditions" IsChecked="False"/>
RadioButton(单选按钮)
单选按钮允许用户在一组选项中选择一个。
<StackPanel>
<RadioButton GroupName="Colors" Content="Red" IsChecked="True" />
<RadioButton GroupName="Colors" Content="Green" />
<RadioButton GroupName="Colors" Content="Blue" />
</StackPanel>
数据绑定:
public class Option : INotifyPropertyChanged
{
private string name;
private bool isSelected;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Option : INotifyPropertyChanged
{
private string name;
private bool isSelected;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="YourNamespace.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>
<ItemsControl ItemsSource="{Binding Options}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Name}"
IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
ComboBox(组合框)
组合框允许用户从下拉列表中选择一个项。
<ComboBox Width="200" SelectedIndex="1">
<ComboBoxItem Content="Option 1" />
<ComboBoxItem Content="Option 2" />
<ComboBoxItem Content="Option 3" />
</ComboBox>
myComboBox.SelectedItem = myComboBox.Items[1]; // 设置第二项为默认选中项
数据绑定:
public partial class MainWindow : Window
{
public ObservableCollection<string> Items { get; set; }
private string selectedItem;
public string SelectedItem
{
get => selectedItem;
set
{
selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
}
}
public MainWindow()
{
InitializeComponent();
Items = new ObservableCollection<string> { "Item 1", "Item 2", "Item 3" };
SelectedItem = Items[1]; // 默认选择第二项
this.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="YourNamespace.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>
<ComboBox ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"/>
</Grid>
</Window>
ListBox(列表框)
列表框用于显示一系列项,用户可以选择其中一个或多个项。
<ListBox Width="200" Height="100">
<ListBoxItem Content="Item 1" />
<ListBoxItem Content="Item 2" />
<ListBoxItem Content="Item 3" />
</ListBox>
数据绑定:
public class ListItem : INotifyPropertyChanged
{
private string name;
private bool isEnabled;
private bool isSelected;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
public bool IsEnabled
{
get => isEnabled;
set
{
isEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
public ObservableCollection<ListItem> ListItems { get; set; }
public MainWindow()
{
InitializeComponent();
ListItems = new ObservableCollection<ListItem>
{
new ListItem { Name = "Item 1", IsEnabled = true },
new ListItem { Name = "Item 2", IsEnabled = false }, // 这个项是禁用的
new ListItem { Name = "Item 3", IsEnabled = true }
};
this.DataContext = this;
}
}
<Window x:Class="YourNamespace.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>
<ListBox ItemsSource="{Binding ListItems}"
SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</Window>
<ListBox Grid.Row="1" x:Name="lbApplist" ItemsSource="{Binding MonitoredAppList}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<local:MonitoredAppConfigControl ></local:MonitoredAppConfigControl>
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Width="200" Height="100" ItemsSource="{Binding People}" DisplayMemberPath="Name">
TreeView(树形结构)
用于显示具有层次结构的数据。
<Window x:Class="TreeViewExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TreeView 示例" Height="350" Width="525">
<Grid>
<TreeView Name="fileTreeView">
<!-- 根节点 -->
<TreeViewItem Header="C:\" IsExpanded="True">
<!-- 子节点 -->
<TreeViewItem Header="Program Files" IsExpanded="True">
<!-- 子节点的子节点 -->
<TreeViewItem Header="Microsoft Office" />
<TreeViewItem Header="Visual Studio" />
</TreeViewItem>
<TreeViewItem Header="Users" IsExpanded="True">
<TreeViewItem Header="Public" />
<TreeViewItem Header="User1" />
</TreeViewItem>
<TreeViewItem Header="Windows" />
</TreeViewItem>
</TreeView>
</Grid>
</Window>
绑定:
public class FileSystemItem
{
public string Name { get; set; }
public ObservableCollection<FileSystemItem> Children { get; set; }
public bool IsFolder { get; set; }
public FileSystemItem(string name, bool isFolder)
{
Name = name;
IsFolder = isFolder;
Children = new ObservableCollection<FileSystemItem>();
}
}
<Window x:Class="TreeViewExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewExample"
Title="TreeView 示例" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<TreeView ItemsSource="{Binding FileSystemItems}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
//初始化数据
public class MainViewModel
{
public ObservableCollection<FileSystemItem> FileSystemItems { get; set; }
public MainViewModel()
{
// 创建根节点
var root = new FileSystemItem("C:\\", true);
// 添加子节点
var programFiles = new FileSystemItem("Program Files", true);
programFiles.Children.Add(new FileSystemItem("Microsoft Office", false));
programFiles.Children.Add(new FileSystemItem("Visual Studio", false));
var users = new FileSystemItem("Users", true);
users.Children.Add(new FileSystemItem("Public", false));
users.Children.Add(new FileSystemItem("User1", false));
root.Children.Add(programFiles);
root.Children.Add(users);
root.Children.Add(new FileSystemItem("Windows", true));
// 将根节点添加到集合中
FileSystemItems = new ObservableCollection<FileSystemItem> { root };
}
}
Slider(滑块)
滑块允许用户在一个范围内选择一个值。
<Slider Minimum="0" Maximum="100" Value="50" Width="200" />
ProgressBar(进度条)
进度条用于显示操作的进度。
<ProgressBar Minimum="0" Maximum="100" Value="70" Width="200" Height="20" />
Image(图像)
图像控件用于显示图片。
<Image Source="image.jpg" Width="100" Height="100"/>
Grid(网格)
Grid是一个常用的布局控件,用于创建行和列的布局。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- 按照控件内部占用空间,自动调整大小 -->
<RowDefinition Height="*" /> <!-- 占用所有剩余空间 (所有包含*的按照比例占满剩余空间) -->
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="Name:" Grid.Row="0" Grid.Column="0" />
<TextBox Grid.Row="0" Grid.Column="1" />
<Button Content="Submit" Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center" /> <!--Column Span表示占几列 -->
</Grid>
StackPanel(堆叠面板)
StackPanel是另一个常用的布局控件,它将子元素按顺序垂直或水平排列。默认是垂直排列
<StackPanel Orientation="Vertical">
<TextBlock Text="First Item" />
<TextBlock Text="Second Item" />
<TextBlock Text="Third Item" />
<TextBlock Text="这个StackPanel是垂直排列的" />
<StackPanel Orientation="Horizontal">
<Button Content="水平按钮 1" />
<Button Content="水平按钮 2" />
</StackPanel>
</StackPanel>
DockPanel(停靠面板)
DockPanel允许子元素停靠在其边缘(顶部、底部、左侧、右侧)或填充剩余空间。
<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="Fill" />
</DockPanel>
Canvas(画布)
Canvas提供了一个绝对定位的布局控件,可以在其上使用坐标指定子元素的位置。
<Canvas>
<Button Content="Click Me" Canvas.Left="50" Canvas.Top="30" />
<TextBox Canvas.Left="50" Canvas.Top="70" Width="100" />
</Canvas>
TabControl(选项卡控件)
TabControl允许用户在多个选项卡页面之间切换。
<TabControl>
<TabItem Header="Tab 1">
<TextBlock Text="Content for Tab 1" />
</TabItem>
<TabItem Header="Tab 2">
<TextBlock Text="Content for Tab 2" />
</TabItem>
</TabControl>
ToolTip
ToolTip 是 WPF 中用于在用户悬停控件时显示的附加信息提示。它可以附加到大多数控件上。
<Button Content="悬停我看看">
<Button.ToolTip>
<ToolTip Content="这是一个提示信息" />
</Button.ToolTip>
</Button>
支持复杂内容
<Button Content="悬停查看更多">
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock Text="提示信息:" FontWeight="Bold"/>
<TextBlock Text="这是详细的提示信息" />
<Image Source="image.jpg" Width="50" Height="50"/>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>
DataGrid
DataGrid
用于显示表格数据,支持排序、过滤、分组以及可编辑的列。它非常适合展示结构化的数据,比如数据库表或列表。
<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding YourDataCollection}" />
-
AutoGenerateColumns="True"
:自动生成列,根据绑定的数据的属性名称。 -
ItemsSource
:绑定的数据源(通常是集合,如ObservableCollection
或List
)。
你可以自定义列,比如文本列、复选框列、模板列等:
<DataGrid ItemsSource="{Binding YourDataCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridCheckBoxColumn Header="Is Active" Binding="{Binding IsActive}" />
<DataGridTemplateColumn Header="Custom Template">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<Button Content="Click" Command="{Binding CustomCommand}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
- 排序:默认支持列排序,点击列头可切换升序和降序。
-
分页:通过外部逻辑实现分页,例如使用
ObservableCollection
控制页面的数据量。 -
编辑功能:将
DataGrid
设置为可编辑,如果需要更好的控制对象的编辑流程,还绑定IEditableObject
接口,这样可以控制对象的编辑,取消和提交,管理编辑对象的生命周期。
<Window x:Class="WPFDataGridExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataGrid 编辑示例" Height="350" Width="525">
<Grid>
<DataGrid x:Name="dataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Persons}"
CanUserAddRows="True"
CanUserDeleteRows="True"
CanUserSortColumns="True"
IsReadOnly="False"
Margin="10"
CellEditEnding="DataGrid_CellEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="姓名" Binding="{Binding Name, Mode=TwoWay}" />
<DataGridTextColumn Header="年龄" Binding="{Binding Age, Mode=TwoWay}" />
<DataGridCheckBoxColumn Header="是否激活" Binding="{Binding IsActive, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
-
AutoGenerateColumns="False"
:我们手动定义列,不自动生成。 -
CanUserAddRows="True"
:允许用户添加行。 -
CanUserDeleteRows="True"
:允许用户删除行。 -
IsReadOnly="False"
:允许编辑单元格。 -
CellEditEnding="DataGrid_CellEditEnding"
:在编辑完成时触发的事件,用于处理保存逻辑。
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WPFDataGridExample
{
public class Person : INotifyPropertyChanged
{
private string name;
private int age;
private bool isActive;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
public int Age
{
get { return age; }
set
{
age = value;
OnPropertyChanged("Age");
}
}
public bool IsActive
{
get { return isActive; }
set
{
isActive = value;
OnPropertyChanged("IsActive");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class MainViewModel
{
public ObservableCollection<Person> Persons { get; set; }
public MainViewModel()
{
Persons = new ObservableCollection<Person>
{
new Person { Name = "Alice", Age = 30, IsActive = true },
new Person { Name = "Bob", Age = 25, IsActive = false },
new Person { Name = "Charlie", Age = 40, IsActive = true }
};
}
}
}
using System.Windows;
namespace WPFDataGridExample
{
public partial class MainWindow : Window
{
private MainViewModel viewModel;
public MainWindow()
{
InitializeComponent();
viewModel = new MainViewModel();
this.DataContext = viewModel;
}
private void DataGrid_CellEditEnding(object sender,
System.Windows.Controls.DataGridCellEditEndingEventArgs e)
{
// 在这里处理单元格编辑完成后的逻辑,比如保存更改
var editedPerson = e.Row.Item as Person;
MessageBox.Show($"你刚刚编辑了:{editedPerson.Name}, 年龄:{editedPerson.Age}, 是否激活:{editedPerson.IsActive}");
}
}
}
MainViewModel
是窗口的数据上下文(DataContext
),包含一个ObservableCollection<Person>
,用于存储和显示表格中的数据。CellEditEnding
事件在编辑单元格时触发,显示编辑后的数据或处理其他逻辑。你可以直接在
DataGrid
中编辑Name
、Age
和IsActive
列的值。可以通过点击表格最下方的空白行添加新的数据。
用户可以通过右键菜单或选择行按
Delete
键删除行。
ListView
用于显示列表数据。
<ListView ItemsSource="{Binding YourDataCollection}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
使用 DataTemplate
可以自定义 ListView
中每一项的外观:
<ListView ItemsSource="{Binding YourDataCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" - " />
<TextBlock Text="{Binding Age}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
-
选择模式:通过
SelectionMode
属性设置单选、多选。 -
分组:通过
CollectionViewSource
实现分组展示。 -
排序和过滤:通过
CollectionView
实现数据的排序和过滤。
ContextMenu
的右键菜单,通常用于为用户提供上下文相关的操作。
<Button Content="右键点击我">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="操作1" />
<MenuItem Header="操作2" />
</ContextMenu>
</Button.ContextMenu>
</Button>
ContextMenu
项目可以绑定命令,以响应用户点击。
<Button Content="右键点击我">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="删除" Command="{Binding DeleteCommand}" />
<MenuItem Header="编辑" Command="{Binding EditCommand}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
可以通过 ItemsSource
动态生成菜单项。
<Button Content="右键点击我">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Name}" Command="{Binding Command}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</Button.ContextMenu>
</Button>
4. Menu
Menu
是一个横向或纵向排列的菜单栏控件,通常用于应用程序的主菜单。
<Menu>
<MenuItem Header="文件">
<MenuItem Header="打开" />
<MenuItem Header="保存" />
<MenuItem Header="退出" />
</MenuItem>
<MenuItem Header="编辑">
<MenuItem Header="复制" />
<MenuItem Header="粘贴" />
</MenuItem>
</Menu>
你可以为 MenuItem
绑定命令,以响应用户选择菜单项。
<Menu>
<MenuItem Header="文件">
<MenuItem Header="打开" Command="{Binding OpenCommand}" />
<MenuItem Header="保存" Command="{Binding SaveCommand}" />
</MenuItem>
</Menu>
MenuItem
可以显示图标,通过 Icon
属性设置。
<Menu>
<MenuItem Header="文件">
<MenuItem Header="打开">
<MenuItem.Icon>
<Image Source="open_icon.png" Width="16" Height="16" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="保存">
<MenuItem.Icon>
<Image Source="save_icon.png" Width="16" Height="16" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
你可以使用 InputGestureText
设置菜单项的快捷键提示,但实际的快捷键绑定需要在 CommandBindings
中设置。
<Menu>
<MenuItem Header="保存" InputGestureText="Ctrl+S" Command="{Binding SaveCommand}" />
</Menu>
ScrollViewer
ScrollViewer
是一个用于包含其他控件并提供水平和垂直滚动功能的容器控件。通常,控件内容超出 ScrollViewer
的边界时会自动显示滚动条。
-
HorizontalScrollBarVisibility
:控制水平滚动条的可见性。-
Disabled
:禁用水平滚动条。 -
Auto
:根据需要自动显示滚动条(当内容超出时显示)。 -
Hidden
:滚动条不可见,但内容依然可以水平滚动。 -
Visible
:始终显示滚动条。
-
-
VerticalScrollBarVisibility
:控制垂直滚动条的可见性,使用方式和HorizontalScrollBarVisibility
相同。 -
CanContentScroll
:如果为True
,表示滚动时基于项(如行、列)进行,而不是基于像素。
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Text="Item 1" Height="100"/>
<TextBlock Text="Item 2" Height="100"/>
<TextBlock Text="Item 3" Height="100"/>
<TextBlock Text="Item 4" Height="100"/>
<!-- 内容超出 ScrollViewer 可视区域时,会显示滚动条 -->
</StackPanel>
</ScrollViewer>
StackPanel
并不自带滚动功能。当 StackPanel
中的内容超出它的可视区域时,控件本身不会自动提供滚动条,通常需要将 StackPanel
放入 ScrollViewer
中。
ListView
自带滚动条功能,当它的内容超出可视区域时,会自动显示垂直和/或水平滚动条。
-
ListView
继承自ItemsControl
,它包含ScrollViewer
控件,可以通过设置ScrollViewer.HorizontalScrollBarVisibility
和ScrollViewer.VerticalScrollBarVisibility
来控制滚动条。<ListView ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"> <ListViewItem>Item 1</ListViewItem> <ListViewItem>Item 2</ListViewItem> <ListViewItem>Item 3</ListViewItem> <ListViewItem>Item 4</ListViewItem> <ListViewItem>Item 5</ListViewItem> </ListView>
你以自定义滚动条的外观,修改滚动条的样式。
例如,通过 ControlTemplate
可以修改滚动条的视觉效果,或者通过 Style
设置其宽度、高度等。
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ScrollViewer.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Width" Value="12"/>
<Setter Property="Background" Value="LightGray"/>
</Style>
</ScrollViewer.Resources>
<StackPanel>
<TextBlock Text="Custom ScrollBar 1" Height="100"/>
<TextBlock Text="Custom ScrollBar 2" Height="100"/>
<TextBlock Text="Custom ScrollBar 3" Height="100"/>
</StackPanel>
</ScrollViewer>
CanContentScroll
和虚拟化
-
CanContentScroll
:在ListView
和DataGrid
中,设置CanContentScroll
为True
时,滚动将基于项进行,而非像素。这意味着滚动时是整行或整列的跳跃。 -
虚拟化:虚拟化是为了提高性能的一种机制,通常在
ListView
、DataGrid
中使用。当启用虚拟化时,控件只会渲染可见的项,未显示的项不会创建,滚动时动态加载。
可以通过 ScrollViewer
的 ScrollToVerticalOffset
或 ScrollToHorizontalOffset
方法手动控制滚动条的位置。
scrollViewer.ScrollToVerticalOffset(100); // 垂直滚动到100的位置
scrollViewer.ScrollToHorizontalOffset(50); // 水平滚动到50的位置
自定义控件
自定义控件允许你创建可重用的控件,封装特定的功能或样式。自定义控件可以分为两种主要类型:
自定义控件(Custom Control):创建新的控件类型,比如自定义一个按钮,可以具有自定义的行为和样式。通常需要定义控件的逻辑和样式,并且可以在 XAML 中使用。
自定义用户控件(Custom UserControl):创建控件的组合,通常用于封装常用的界面元素或布局。用户控件是对现有控件的组合和封装,可以在 XAML 中直接使用。
自定义控件
using System.Windows;
using System.Windows.Controls;
namespace MyCustomControls
{
public class MyCustomButton : Control
{
static MyCustomButton()
{
// 设置默认样式
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomButton),
new FrameworkPropertyMetadata(typeof(MyCustomButton)));
}
// 自定义属性
public static readonly DependencyProperty CustomProperty = DependencyProperty.Register(
"Custom", typeof(string), typeof(MyCustomButton), new PropertyMetadata("Default"));
public string Custom
{
get { return (string)GetValue(CustomProperty); }
set { SetValue(CustomProperty, value); }
}
}
}
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyCustomControls">
<Style TargetType="{x:Type local:MyCustomButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomButton}">
<Border Background="LightBlue" BorderBrush="DarkBlue" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Style>
</ResourceDictionary>
在 XAML 文件中引入自定义控件的命名空间,然后像使用其他控件一样使用自定义控件。
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyCustomControls"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MyCustomButton Custom="Hello World" Width="200" Height="50"/>
</Grid>
</Window>
自定义用户控件
用户控件通常继承自 UserControl
类,可以包含 XAML 和后台代码。
<!-- MyUserControl.xaml -->
<UserControl x:Class="MyUserControls.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock Text="{Binding CustomText, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Grid>
</UserControl>
// MyUserControl.xaml.cs
using System.Windows.Controls;
namespace MyUserControls
{
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
public static readonly DependencyProperty CustomTextProperty =
DependencyProperty.Register("CustomText", typeof(string), typeof(MyUserControl), new PropertyMetadata("Default"));
public string CustomText
{
get { return (string)GetValue(CustomTextProperty); }
set { SetValue(CustomTextProperty, value); }
}
}
}
在 XAML 文件中引入用户控件的命名空间,然后像使用其他控件一样使用自定义用户控件。
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyUserControls"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MyUserControl CustomText="Hello User Control" Width="200" Height="100"/>
</Grid>
</Window>