容器控件:
- Grid
- stackPanel
- WrapPanel
- DockPanel
- UniformGrid
Grid:
- Grid.RowDefinitions
- RowDefinition
- Grid.ColumnDefinitions
- ColumnDefinition
第一行的高度是第二行的2倍
<RowDefinition Height="2*"/> 100 auto
占2列的空间
<Border Grid.ColumnSpan="2" Background="Red"/>
stackPanel:
一般用来修饰部分容器,一般是垂直居中的水平
水平排列
<StackPanel Orientation="Horizontal">
WrapPanel:
默认是贴着上面水平,会自动换行
DockPanel:
最后一个元素会填充剩余的空间
最后一个元素不填充剩余空间:
LastChildFill="False"
元素停靠的方向:
DockPanel.Dock="Top"
UniformGrid:
设置3行3列,会平均分配。即使不设置行和列的数量也会均匀分配:
Rows="3" Columns="3"
样式:
为了复用
将这个:
<Button Content="按我0" FontSize="18" Foreground="White" Background="red"/>
<Button Content="按我1" FontSize="18" Foreground="White" Background="red"/>
<Button Content="按我2" FontSize="18" Foreground="White" Background="red"/>
改为这个:
<Window.Resources>
<Style x:Key="btn0" TargetType="Button">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="red"/>
</Style>
</Window.Resources>
<Button Content="按我0" Style="{StaticResource btn0}"/>
<Button Content="按我1" Style="{StaticResource btn0}"/>
<Button Content="按我2" Style="{StaticResource btn0}"/>
样式还可以继承,例如,注意BasedOn:
<Window.Resources>
<Style x:Key="btn0" TargetType="Button">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="red"/>
</Style>
<Style x:Key="btn1" TargetType="Button" BasedOn="{StaticResource btn0}">
</Style>
</Window.Resources>
控件模板:
为了把wpf的模板更加自定义的改造
数据模板:
<ListBox x:Name="list"/>
<ListBox x:Name="list">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" Background="{Binding Code}"/>
<TextBlock Text="{Binding Name}" Margin="10,0"/>
</StackPanel>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
List<MyColor> colors = new List<MyColor>
{
new MyColor() { Code = "pink", Name = "粉红" },
new MyColor() { Code = "red", Name = "红色" },
new MyColor() { Code = "green", Name = "绿色" },
new MyColor() { Code = "blue", Name = "蓝色" }
};
list.ItemsSource = colors;
或者可以这样写表格:
<DataGrid x:Name="grid" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Code" Binding="{Binding Code}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="删除"/>
<Button Content="复制"/>
<Button Content="保存"/>
</StackPanel>
<!--<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" Background="{Binding Code}"/>
<TextBlock Margin="10,0" Text="{Binding Name}"/>
</StackPanel>-->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
WPF双向绑定:
双向绑定:
<StackPanel>
<Slider x:Name="slider0" Margin="5"/>
<TextBox x:Name="tb0" Text="{Binding ElementName=slider0,Path=Value,Mode=Default}" Margin="5" Height="30"/>
</StackPanel>
或者这样绑定类:
<TextBox x:Name="tb1" Text="{Binding Name}" Margin="5" Height="30"/>
this.DataContext = new Class1() { Name="tom" };
internal class Class1
{
public string Name { get; set; }
}
WPF的命令模式:
<Button Content="点我" Command="{Binding ShowCommand}"/>
this.DataContext = new MainViewModel();
public class MyCommand : ICommand
{
Action executeAction;
public MyCommand(Action action)
{
this.executeAction = action;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
executeAction();
}
}
internal class MainViewModel
{
public MyCommand ShowCommand { get; set; }
public MainViewModel()
{
ShowCommand = new MyCommand(show);
}
public void show()
{
MessageBox.Show("点击了按钮");
}
}
如果还想以命令模式修改界面的文本,需要以下调整:
internal class MainViewModel : INotifyPropertyChanged
{
public MyCommand ShowCommand { get; set; }
private string name;
public string Name
{
get { return name; }
set
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
public MainViewModel()
{
ShowCommand = new MyCommand(show);
Name = "hello";
}
public void show()
{
Name = "点击了按钮";
MessageBox.Show("点击了按钮");
}
public event PropertyChangedEventHandler PropertyChanged;
}
或者我们将代码封装一下:
internal class MainViewModel : ViewModelBase
{
public MyCommand ShowCommand { get; set; }
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged();
}
}
private string title;
public string Title
{
get { return title; }
set
{
title = value;
OnPropertyChanged();
}
}
public MainViewModel()
{
ShowCommand = new MyCommand(show);
Name = "hello";
}
public void show()
{
Name = "点击了按钮";
Title = "点击了按钮";
MessageBox.Show("点击了按钮");
}
}
internal class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName="")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}