深入探索WPF应用开发:布局、控件与数据绑定
立即解锁
发布时间: 2025-08-20 01:13:16 订阅数: 1 


C#面向对象编程与Web服务开发
# 深入探索WPF应用开发:布局、控件与数据绑定
## 1. 布局控件的运用
在WPF窗口中,虽然可以使用固定定位来放置控件,但这种方式并不推荐。固定定位在固定分辨率下效果较好,但在不同分辨率和设备上的扩展性不佳。为克服这一局限,WPF提供了多种布局控件。
### 1.1 Grid控件
Grid是用于定位其他控件的主要布局控件之一。它包含列和行,用于控制子控件的放置。列和行的高度和宽度可以设置为固定值、auto或*。auto设置会占用包含控件所需的空间,*设置会占用可用的所有空间。
以下是一个使用Grid控件布局的简单数据输入表单示例:
```xml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="28" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Name:"/>
<Label Grid.Row="1" Grid.Column="0" Content="Old Password:"/>
<Label Grid.Row="2" Grid.Column="0" Content="New Password:"/>
<Label Grid.Row="3" Grid.Column="0" Content="Confirm Password:"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" />
<TextBox Grid.Column="1" Grid.Row="2" Margin="3" />
<TextBox Grid.Column="1" Grid.Row="3" Margin="3" />
<Button Grid.Column="1" Grid.Row="4" HorizontalAlignment="Right"
MinWidth="80" Margin="0,0,0,8" Content="Submit" />
</Grid>
```
### 1.2 StackPanel控件
StackPanel根据方向设置垂直或水平布局子控件。以下是一个在StackPanel控件中包含两个按钮的示例:
```xml
<StackPanel Grid.Column="1" Grid.Row="4" Orientation="Horizontal" >
<Button MinWidth="80" Margin="0,0,0,8" Content="Submit" />
<Button MinWidth="80" Margin="0,0,0,8" Content="Cancel" />
</StackPanel>
```
### 1.3 其他布局控件
除了Grid和StackPanel,还有DockPanel、WrapPanel和Canvas等布局控件。
- DockPanel:用于将元素停靠在面板的左侧、右侧、顶部、底部或中心。
- WrapPanel:类似于StackPanel,但如果没有足够空间,会将子控件换行显示。
- Canvas:用于相对于其一侧以绝对定位方式布局子元素,通常用于图形元素,而非用户界面控件。
## 2. 添加显示控件
大多数业务应用的目标是向用户展示数据,并允许他们更新数据并保存回数据库。常用的控件包括TextBox、ListBox、ComboBox、Checkbox、DatePicker和DataGrid。
以下是一个向窗口添加ListBox和ComboBox的示例:
```xml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox Margin="20" Grid.Column="0">
<ListBoxItem>Red</ListBoxItem>
<ListBoxItem>Blue</ListBoxItem>
<ListBoxItem>Green</ListBoxItem>
<ListBoxItem>Yellow</ListBoxItem>
</ListBox>
<ComboBox Grid.Column="1" VerticalAlignment="Top">
<ComboBoxItem>Small</ComboBoxItem>
<ComboBoxItem>Medium</ComboBoxItem>
<ComboBoxItem>Large</ComboBoxItem>
<ComboBoxItem>X-Large</ComboBoxItem>
</ComboBox>
</Grid>
```
虽然可以直接在XAML标记中编写这些控件显示的项目,但更可能使用数据绑定来显示其值。
## 3. 使用Visual Studio设计器
虽然可以使用文本编辑器通过代码完全创建窗口,但这个过程可能很繁琐且效率不高。幸运的是,Visual Studio IDE包含一个优秀的设计器,用于创建WPF窗口。使用设计器,可以从工具箱将控件拖放到Visual Studio设计器中,使用Visual Studio属性窗口设置其属性,并在使用XAML编辑器输入代码时获得自动完成和语法检查的好处。
## 4. 处理控件事件
Windows图形用户界面(GUI)程序是事件驱动的。事件是由用户或系统发起的操作,例如用户单击按钮或SqlConnection对象发出StateChange事件。事件驱动的应用程序通过执行指定的代码来响应发生的各种事件。
### 4.1 事件处理机制
.NET Framework使用委托来绑定事件,委托对象维护一个已订阅接收事件通知的方法的调用列表。当事件发生时,控件会通过调用事件的委托来引发事件,委托会调用已订阅接收事件通知的事件处理方法。
### 4.2 添加事件处理程序
在Visual Studio中,可以通过编写XAML代码或在控件的属性窗口中选择来为WPF控件添加事件。
以下是一个按钮点击事件的事件处理方法示例:
```csharp
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
}
```
事件处理方法的名称通常以发出事件的对象名称开头,后跟下划线(_)和事件名称。所有事件处理程序必须提供两个参数:sender表示发起事件的对象,RoutedEventArgs用于传递特定于事件的信息。
### 4.3 处理多个按钮的点击事件
可以使用同一个方法处理多个具有相同签名的事件。以下是一个处理两个按钮点击事件的示例:
```csharp
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
if (btn.Name == "btnCancel")
{
//Cancel code goes here
}
else if (btn.Name == "btnSubmit")
{
//Submit code goes here
}
}
```
## 5. 创建备忘录查看器应用程序
接下来,我们将创建一个简单的备忘录查看器应用程序,允许用户加载和查看备忘录文档。
### 5.1 创建备忘录查看器界面
创建备忘录查看器界面的步骤如下:
1. 启动Visual Studio,选择“文件” -> “新建” -> “项目”。
2. 在C#项目文件夹下选择WPF应用程序,将项目重命名为activity11_1,然后点击“确定”按钮。
3. 项目包含一个MainWindow.xaml文件,用于设计用户界面;还包含一个MainWindow.xaml.cs文件,用于添加响应事件的代码。如果未打开,在XAML编辑器窗口中打开MainWindow.xaml文件。
4. 在XAML标记的Window标签中,添加一个名称属性,值为“Memoviewer”,并将标题属性更改为“Memo viewer”。
```xml
<Window x:Name="Memoviewer" x:Class="Act11_1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Memo Viewer" Height="350" Width="525">
```
5. 在Grid控件中添加一个DockPanel控件。
```xml
<Grid>
<DockPanel LastChildFill="True">
</DockPanel>
</Grid>
```
6. 在DockPanel内部添加一个Menu控件,并使用以下XAML将其停靠在顶部:
```xml
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Name="mnuNew" Header="_New... " />
<Separator />
<MenuItem Name="mnuOpen" Header="_Open... " />
<Separator />
<MenuItem Name="mnuSave" Header="_Save" />
<MenuItem Name="mnuSaveAs" Header="_Save As... " />
<Separator />
<MenuItem Name="mnuExit" Header="_Exit" />
</MenuItem>
<MenuItem Header="_Edit">
<MenuItem Header="_Cut... " />
<MenuItem Header="_Copy... " />
<MenuItem Header="_Paste" />
</MenuItem>
</Menu>
</DockPanel>
```
7. 在结束的Menu标签和结束的DockPanel标签之间插入以下代码,添加一个StatusBar控件。注意,在StatusBar控件内部使用Grid控件来布局StatusBar中的项目。
```xml
<StatusBar DockPanel.Dock="Bottom">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<StatusBarItem Grid.Column="0" HorizontalAlignment="Left">
<TextBlock Name="sbTextbox1">File Name</TextBlock>
</StatusBarItem>
<StatusBarItem Grid.Column="1" HorizontalAlignment="Right">
<TextBlock Name="sbTextbox2">Date</TextBlock>
</StatusBarItem>
</StatusBar>
```
8. 在StatusBar结束标签之后和DockPanel结束标签之前添加一个RichTextBox控件。
```xml
</StatusBar>
<RichTextBox Name="rtbMemo" />
</DockPanel>
```
9. 注意,随着添加XAML,Visual Designer会更新窗口的外观。备忘录查看器窗口应类似于所示的窗口。
10. 构建解决方案,如果有任何错误,修复后重新构建。
### 5.2 编码控件事件
编码控件事件的步骤如下:
1. 在XAML编辑器窗口中,向Window添加Loaded事件属性,如下所示:
```xml
<Window x:Class="Act11_1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="MemoViewer" Title="Memo Viewer" Height="350" Width="525"
Loaded="MemoViewer_Loaded">
```
2. 右键单击XAML代码编辑器,选择“查看代码”,打开代码隐藏文件。在MemoViewer_Loaded事件处理程序中添加以下代码。当窗口加载时,应在StatusPanel的左侧显示消息,在右侧显示日期。
```csharp
private void MemoViewer_Loaded(object sender, RoutedEventArgs e)
{
sbTextbox1.Text = "Ready to load file";
sbTextbox2.Text = DateTime.Today.ToShortDateString();
}
```
3. 在XAML编辑器中,向mnuOpen控件添加Click事件。
```xml
<MenuItem Name="mnuOpen" Header="_Open... "
Click="mnuOpen_Click"/>
```
4. 在代码隐藏文件的代码编辑器窗口中,向菜单点击事件添加以下代码。此代码配置并启动一个打开文件对话框,返回文件路径。然后将文件路径传递给FileStream对象,将文件加载到RichTextBox中。文件路径也会加载到StatusBar的TextBox中。
```csharp
private void mnuOpen_Click(object sender, RoutedEventArgs e)
{
// Configure open file dialog box
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process open file dialog box results
if (result == true)
{
// Open document and load RichTextBox
string fileName = dlg.FileName;
TextRange range;
System.IO.FileStream fStream;
if (System.IO.File.Exists(fileName))
{
range = new TextRange(rtbMemo.Document.ContentStart,
```
0
0
复制全文
相关推荐










