WPF学习笔记
WPF
一、WPF基础布局控件
WPF六大常用布局元素:
- 、Grid:网格。可以自定义行和列并通过行列的数量、行高列宽来调整控件的布局,近似HTML代码中的table。
- 、DockPanel:泊靠式面板。内部元素可以选择泊靠的方向(上下左右),类似于Winform中设置控件的Dock属性。
- 、StackPanel:栈式面板。可将包含的元素在水平或垂直方向排成一条线,当移除一个元素后,后面的元素会自动向前填充空缺(菜单栏经常用到此布局)。
- 、WrapPanel:自动折行面板。内部元素在排满一行后能够自动折行,类似于Html中的流式布局。
- 、Canvas:画布。内部元素可以使用以像素为单位的绝对坐标进行定位,类似于Windows Form 的布局方式。
二、Window.Resources
用于存储一些WPF窗体的一些公共样式,然后通过x:key的属性去调用。
1.Style:
各个控件内部都继承了该样式,可以通过该样式去改变控件的样式
TargetType:表示该样式所属的控件类型,例如Button、Image…
BasedOn:表示该样式所继承的父类。
Triggers:表示该样式触发的条件。
Setters:表示该样式需要改变的一些属性。
<Window x:Class="glenz.WRP1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:glenz.WRP1"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="600">
<Window.Resources>
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Black"/>
<Setter Property="Content" Value="Hellow"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style x:Key="ButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
</Style>
</Window.Resources>
<Grid>
<StackPanel >
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
</StackPanel>
</Grid>
</Window>
2.ControlTemplate
<Grid>
<StackPanel>
<Button Style="{DynamicResource ButtonStyle1}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Button Content="1"/>
<Button Content="1"/>
<Button Content="1"/>
</Button.Content>
</Button>
</StackPanel>
</Grid>
-
public object Content { get; set; }
由于Content是object类型的,所以它可以承载复杂的数据类型
3.DataTemplate
通过绑定数据来绑定模版,视图页面代码
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<!--<ListBox x:Name="dataGrid">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
--><!--每一个属性都可以通过Binding来进行绑定--><!--
<Border Width="10" Height="10" Background = "{Binding Code}"/>
<TextBlock Text="{Binding Name}" Margin="15,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>-->
<DataGrid AutoGenerateColumns="False" CanUserAddRows ="False" x:Name ="dataGrid">
<!--先指定对应的列-->
<DataGrid.Columns>
<!--设置列的模版-->
<DataGridTemplateColumn>
<!--设置列中单元格的模版-->
<DataGridTemplateColumn.CellTemplate>
<!--设置数据模版-->
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" Background = "{Binding Code}"/>
<TextBlock Text="{Binding Name}" Margin="15,0" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
后端代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
test();
}
private void test()
{
dataGrid.ItemsSource = new List<Color>()
{
new Color() { Code = "Pink" ,Name = "粉红" },
new Color() { Code = "Crimson" ,Name = "猩红" },
new Color() { Code = "LavenderBlush" ,Name = "淡紫色" },
new Color() { Code = "PaleVioletRed" ,Name = "紫罗兰红色" },
};
// Pink 粉红 #FFC0CB 255,192,203
//Crimson 猩红 #DC143C 220,20,60
//LavenderBlush 脸红的淡紫色 #FFF0F5 255,240,245
//PaleVioletRed 苍白的紫罗兰红色 #DB7093 219,112,147
//HotPink 热情的粉红 #FF69B4 255,105,180
//DeepPink 深粉色
}
public class Color
{
public string? Code { get; set; }
public string? Name { get; set; }
}
}
4.数据绑定
<StackPanel>
<Slider x:Name = "slider"/>
<TextBox Text = "{Binding ElementName=slider, Path=Value,Mode=Default}"/>
<TextBox Text = "{Binding ElementName=slider, Path=Value,Mode=OneTime}"/>
<TextBox Text = "{Binding ElementName=slider, Path=Value,Mode=OneWay}"/>
<TextBox Text = "{Binding ElementName=slider, Path=Value,Mode=OneWayToSource}"/>
</StackPanel>
ElementName:绑定的控件的名字
Path:绑定的控件的属性值
Mode:绑定的方法模式,
- Default:默认为双向绑定,
- OneTime:只绑定第一次的值
- OneWay:只绑定绑定的控件的值
- OneWayToSource:只绑定当前数据的值
5.事件绑定
通过ICommand命令来绑定数据
1、建立MyCommand实现ICommand
public class MyCommand : ICommand
{
//建立委托,绑定事件
public Action executeAction;
public MyCommand(Action action)
{
//通过构造函数将委托的方法传进来
this.executeAction = action;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter)
{
return true;
}
//ICommand执行的方法
public void Execute(object? parameter)
{
executeAction();
}
}
2、建立MyViewModel,把需要的数据在这里面进行处理
先在MainView中DataContext进行绑定
this.DataContext = new MyViewModel();
public class MyViewModel
{
public MyViewModel()
{
ShowCommand = new MyCommand(Show);
}
//通过new将方法传入委托
public MyCommand ShowCommand { get; set; }
public void Show()
{
MessageBox.Show("Hello World!!");
}
}
3、在Xaml中进行绑定
绑定的名字要和ViewModel中的委托一样
<Grid>
<Button Command="{Binding ShowCommand}"/>
</Grid>
6.属性值通知更改
1、建立ViewModelBase,继承INotifyPropertyChanged类
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
//CallerMemberName获取方法或属性的名字
public void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
2、在MyViewModel中实现属性的通知更改
继承ViewModelBase类,通过ViewModelBase类中定义的OnPropertyChanged()方法实现属性更改的通知,在Set中实现更改。
public class MyViewModel:ViewModelBase
{
public MyViewModel()
{
ShowCommand = new MyCommand(Show);
}
private string name;
public string Name
{
get { return name; }
set {
name = value;
OnPropertyChanged();
}
}
//通过new将方法传入委托
public MyCommand ShowCommand { get; set; }
public void Show()
{
Name = "Hello World!!";
MessageBox.Show("Hello World!!");
}
}