一、Panel布局
- Grid 网格布局,以表格形式布局元素
- Stack栈布局,元素按一行或一列排布
- Warp 环绕布局,元素按一行或一列排布,到达边界时,自动换行
- Dock 停靠布局,默认情况下,最后一个元素会填充剩余空间,LastChildFill
- UniformGrid 均布网格,不用定义行列,会根据元素自动均匀排布,大小相同
二、样式
<Window.Resources>
<Style TargetType="Border" x:Key="base">
<Setter Property="CornerRadius" Value="15"></Setter>
</Style>
<Style TargetType="Border" BasedOn="{StaticResource base}">
<Setter Property="CornerRadius" Value="15"></Setter>
</Style>
</Window.Resources>
x:Key 指定该值时,具体应用该样式需要style="" TargetType 目标类型 必须 Property 样式属性 Value 值 BasedOn 继承样式
三、控件模板
ControlTemplate 承载更多复杂控件
四、数据绑定
1、ListBox模板 x:Name 指定模板的名称
<ListBox x:Name="list">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" CornerRadius="10" Background="{Binding Color}"></Border>
<TextBlock Margin="10,0" Text="{Binding Name}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
2、Grid模板
<DataGrid x:Name="list1" AutoGenerateColumns="False" CanUserAddRows="False" CanUserSortColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="序号" Binding="{Binding Index}"></DataGridTextColumn>
<DataGridTextColumn Header="姓名" Binding="{Binding Name}"></DataGridTextColumn>
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="编辑"></Button>
<Button Content="删除" Margin="10,0"></Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
五、WPF绑定
为了使两个控件之间互相影响(a改变影响b),之前使用事件驱动的方式,导致代码十分啰嗦 使用binding ElementName
<StackPanel Orientation="Vertical">
<Slider x:Name="slider"></Slider>
<TextBox Text="{Binding ElementName=slider,Path=Value}"></TextBox>
<TextBox Text="{Binding ElementName=slider,Path=Value,Mode=OneWay}"></TextBox>
<TextBox Text="{Binding Name}"></TextBox>
</StackPanel>
后端代码使用 this.DataContext = new ListColor() { Name = "2222" };
六、ICommand
xmal:
<Button Content="bt1" Command="{Binding ShowCommand}"></Button>
定义响应类,继承ICommand
public class ShowComand : ICommand
{
public event EventHandler CanExecuteChanged;
Action showAction;
public ShowComand(Action action)
{
showAction = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
showAction();
}
}
定义model
public class MainWindowModel
{
public MainWindowModel()
{
ShowCommand = new ShowComand(show);
}
public ShowComand ShowCommand { get; set; }
public string Name { get; set; }
private void show()
{
MessageBox.Show("我被点击了");
}
}
this.DataContext = new MainWindowModel() { Name = "2222" };
按钮被点击时,会触发ShowCommand中的Execute方法。
解决了事件耦合,只需要使用属性即可
七、INotifyPropertyChanged
属性值改变通知
当后端代码改变Name的值时,UI层并没有发生改变,所以需要属性通知UI层进行更改数据
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if(PropertyChanged!=null) PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
}
ViewModelBase类,继承INotifyPropertyChanged,实现其接口,提供PropertyChanged事件调用,调用PropertyChanged即可对UI层数据进行更新。 CallerMemberName 特性是 不需要传递属性名,会自动查找。
model层继承ViewModelBase类,属性改变时,调用OnPropertyChanged方法即可。