WPF基础知识
一、WPF 概述
- WPF 是什么:
- WPF(Windows Presentation Foundation)是微软推出的一款用于创建桌面应用程序用户界面的框架。它提供了一种统一的编程模型,将用户界面的设计、布局、数据绑定、动画等功能集成在一起,使得开发人员能够创建出具有丰富交互性和视觉效果的应用程序。
- 它基于.NET Framework,利用了.NET 的强大功能,如面向对象编程、垃圾回收、多线程等,同时结合了 DirectX 技术来实现高性能的图形渲染。
- WPF 的优势:
- 强大的图形渲染能力:WPF 能够实现高质量的 2D 和 3D 图形绘制,支持硬件加速,使得应用程序的界面更加流畅和美观。例如,可以轻松创建具有渐变、阴影、透明等效果的按钮、窗口等控件。
- 数据绑定机制:WPF 提供了强大的数据绑定功能,能够将 UI 元素与业务逻辑中的数据进行双向绑定。当数据发生变化时,UI 会自动更新;反之,当用户在 UI 上进行操作改变了数据,也会自动反映到业务逻辑中。这大大简化了应用程序的开发,减少了代码量,提高了代码的可维护性。
- 布局系统:WPF 具有灵活的布局系统,允许开发人员根据不同的屏幕尺寸和分辨率,轻松地调整 UI 元素的位置和大小。通过使用各种布局容器,如 Grid、StackPanel、DockPanel 等,可以实现复杂的界面布局。
- 样式和模板:可以通过样式和模板来统一和定制应用程序的外观和风格。开发人员可以创建自定义的样式和模板,然后将其应用到多个 UI 元素上,实现一致的视觉效果,并且可以方便地进行修改和更新。
二、C# 语言基础
- 变量和数据类型:
- 值类型:包括整数类型(如 int、long 等)、浮点类型(如 float、double 等)、字符类型(char)、布尔类型(bool)等。值类型的变量直接存储数据值。例如:
int age = 25;
double salary = 5000.5;
char gender = 'M';
bool isStudent = true;
- 引用类型:如字符串(string)、数组、类、接口等。引用类型的变量存储的是对象在内存中的地址。例如:
string name = "John";
int[] numbers = { 1, 2, 3, 4, 5 };
- 控制流语句:
- if - else 语句:用于根据条件执行不同的代码块。例如:
int score = 85;
if (score >= 60)
{
Console.WriteLine("及格");
}
else
{
Console.WriteLine("不及格");
}
- switch 语句:根据不同的表达式值执行不同的分支。例如:
int dayOfWeek = 3;
switch (dayOfWeek)
{
case 1:
Console.WriteLine("星期一");
break;
case 2:
Console.WriteLine("星期二");
break;
case 3:
Console.WriteLine("星期三");
break;
// 其他情况
default:
Console.WriteLine("无效的星期数");
break;
}
- 循环语句:包括 for 循环、while 循环和 do - while 循环。例如,使用 for 循环计算 1 到 100 的和:
int sum = 0;
for (int i = 1; i <= 100; i++)
{
sum += i;
}
Console.WriteLine("1到100的和为:" + sum);
- 方法:是一段可重复使用的代码块,用于实现特定的功能。方法可以有参数和返回值。例如:
public static int Add(int num1, int num2)
{
return num1 + num2;
}
// 调用方法
int result = Add(5, 3);
Console.WriteLine("结果为:" + result);
三、WPF 中的 XAML
- XAML 基础:
- XAML(eXtensible Application Markup Language)是一种用于描述 WPF 应用程序用户界面的标记语言。它与 HTML 类似,但具有更强大的功能和更严格的语法。XAML 将 UI 元素的定义与代码分离,使得 UI 的设计可以由设计师独立完成,而开发人员则专注于业务逻辑的实现。
- 在 XAML 中,每个 UI 元素都对应一个.NET 类。例如,
<Button>
元素对应着System.Windows.Controls.Button
类。可以通过 XAML 的属性来设置 UI 元素的各种属性,如Content
属性用于设置按钮上显示的文本,Width
和Height
属性用于设置按钮的大小等。例如:
<Button Content="点击我" Width="100" Height="30" />
- 布局容器:
- Grid:是一种基于网格的布局容器,它将界面划分为行和列,UI 元素可以放置在不同的单元格中。例如:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="按钮1" />
<TextBox Grid.Row="0" Grid.Column="1" />
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<ListBoxItem>项目1</ListBoxItem>
<ListBoxItem>项目2</ListBoxItem>
</ListBox>
</Grid>
- StackPanel:按照水平或垂直方向依次排列子元素。例如:
<StackPanel Orientation="Horizontal">
<Button Content="按钮1" />
<Button Content="按钮2" />
<Button Content="按钮3" />
</StackPanel>
- DockPanel:可以将子元素停靠在父容器的边缘。例如:
<DockPanel>
<Button DockPanel.Dock="Top" Content="顶部按钮" />
<Button DockPanel.Dock="Bottom" Content="底部按钮" />
<Button DockPanel.Dock="Left" Content="左侧按钮" />
<Button DockPanel.Dock="Right" Content="右侧按钮" />
<TextBlock DockPanel.Dock="Fill" Text="中间文本" />
</DockPanel>
- 数据绑定:在 XAML 中可以方便地实现数据绑定。首先需要在代码中定义一个数据源,然后在 XAML 中使用
Binding
标记将 UI 元素的属性与数据源的属性进行绑定。例如,假设有一个Person
类:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
在 XAML 中可以这样绑定:
<Window.DataContext>
<local:Person Name="张三" Age="30" />
</Window.DataContext>
<Grid>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" Margin="0,20,0,0" />
</Grid>
四、WPF 中的代码隐藏
- 窗口类和事件处理:
- 在 WPF 中,每个窗口都是一个继承自
System.Windows.Window
类的实例。可以在代码隐藏文件中定义窗口的各种行为和事件处理程序。例如,当窗口加载时执行一些初始化操作,可以处理Loaded
事件:
- 在 WPF 中,每个窗口都是一个继承自
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// 在这里进行初始化操作
TextBlock textBlock = new TextBlock();
textBlock.Text = "窗口已加载";
this.Content = textBlock;
}
}
- 对于按钮的点击事件等,也可以在代码隐藏中进行处理。首先在 XAML 中为按钮添加
Click
事件属性:
<Button Content="点击我" Click="Button_Click" />
然后在代码隐藏文件中定义Button_Click
事件处理程序:
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("按钮被点击了");
}
- 与 XAML 的交互:
- 可以在代码隐藏中访问 XAML 中定义的 UI 元素,并对其进行操作。例如,在 XAML 中有一个
TextBox
和一个Button
,当点击按钮时,将TextBox
中的文本显示在MessageBox
中:
- 可以在代码隐藏中访问 XAML 中定义的 UI 元素,并对其进行操作。例如,在 XAML 中有一个
<Grid>
<TextBox x:Name="textBox1" />
<Button Content="获取文本" Click="Button_Click" />
</Grid>
在代码隐藏中:
private void Button_Click(object sender, RoutedEventArgs e)
{
string text = textBox1.Text;
MessageBox.Show("输入的文本是:" + text);
}
- 也可以在代码中动态地创建 UI 元素并添加到 XAML 界面中。例如:
private void CreateButton_Click(object sender, RoutedEventArgs e)
{
Button newButton = new Button();
newButton.Content = "新按钮";
newButton.Click += NewButton_Click;
grid1.Children.Add(newButton);
}
private void NewButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("新按钮被点击了");
}
五、WPF 中的数据绑定进阶
- 实现
INotifyPropertyChanged
接口:- 当数据模型中的属性值发生变化时,为了让 UI 能够及时更新,需要实现
INotifyPropertyChanged
接口。该接口定义了一个PropertyChanged
事件,当属性值改变时,需要触发这个事件来通知 UI 进行更新。例如:
- 当数据模型中的属性值发生变化时,为了让 UI 能够及时更新,需要实现
using System.ComponentModel;
public class Person : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
private int age;
public int Age
{
get { return age; }
set
{
age = value;
OnPropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
- 使用
ObservableCollection
:- 当需要在 UI 中显示一个可观察的集合时,可以使用
ObservableCollection
类。它会在集合发生添加、删除、修改等操作时自动通知 UI 进行更新。例如:
- 当需要在 UI 中显示一个可观察的集合时,可以使用
using System.Collections.ObjectModel;
public class MainWindowViewModel
{
public ObservableCollection<string> Items { get; set; }
public MainWindowViewModel()
{
Items = new ObservableCollection<string>();
Items.Add("项目1");
Items.Add("项目2");
Items.Add("项目3");
}
public void AddItem(string item)
{
Items.Add(item);
}
public void RemoveItem(string item)
{
Items.Remove(item);
}
}
在 XAML 中可以这样绑定:
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<ListBox ItemsSource="{Binding Items}" />
<Button Content="添加项目" Click="AddButton_Click" />
<Button Content="删除项目" Click="RemoveButton_Click" />
</Grid>
在代码隐藏中:
private void AddButton_Click(object sender, RoutedEventArgs e)
{
MainWindowViewModel viewModel = (MainWindowViewModel)this.DataContext;
viewModel.AddItem("新项目");
}
private void RemoveButton_Click(object sender, RoutedEventArgs e)
{
MainWindowViewModel viewModel = (MainWindowViewModel)this.DataContext;
viewModel.RemoveItem("项目1");
}