这部分用来引入资源文件,和html的link script类似

布局方式

Grid布局

页面以表格方式来表现出来,每一块都是格子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Grid>  
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Background="Aqua"></Border>
<Border Grid.Row="0" Grid.Column="1" Background="Red"></Border>
<Border Grid.Row="1" Grid.Column="0" Background="Green"></Border>
<Border Grid.Row="1" Grid.Column="1" Background="Yellow"></Border>
</Grid>


Grid.RowDefinitions:该标签内通过RowDefinition标签的数量来定义行数
Grid.ColumnDefinitions:该标签内通过ColumnDefinition标签的数量来定义列数
后续的其他标签可以通过Grid.RowGrid.Column属性来设定行和列的位置
起始下标从0开始

给元素分别设定Grid.ColumnSpan和Grid.RowSpan属性,可以设置它们占据格子的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<Grid>  
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">占据两行</Button>
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">占据两列</Button>
<Button Grid.Row="0" Grid.Column="1"></Button>
<Button Grid.Row="1" Grid.Column="2"></Button>
</Grid>
</Grid>


当没给元素设定固定列宽(Width)属性时,元素都是根据内容自适应大小

常用元素

  1. Button:按钮
  2. TextBlock:label
  3. TextBox:输入框
  4. DataGrid:表格

一些元素通用的属性

  1. Grid.Row:设定行号
  2. Grid.Column:设定列号
  3. Background:设定背景颜色
  4. HorizontalAlignment:设置对齐
  5. VerticalAlignment:设置垂直对齐
  6. Margin:设置外边距
  7. Padding:设置内边距
    1. 外边距和内边距顺序是左上右下,顺时针方向,两个参数则为左右,上下
  8. height:设置固定的高
  9. width:设置固定的宽
  10. Opacity:设置透明度

DateGrid

Columns属性

  • DataGridTextColumn:表示文本内容的列
  • DataGridCheckBoxColumn:表示复选框的列
  • DataGridComboBoxColumn:表示下拉框的列
  • DataGridTemplateColumn:表示模板的列(万金油)
    更多属性
    参考DataGrid数据表格控件 - WPF中文网 - 从小白到大佬 (wpfsoft.com)
    DataGrid是实际的元素,Grid是布局方式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <Grid>  
    <Grid.ColumnDefinitions>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <DataGrid x:Name="datagrid" SelectionMode="Extended"
    IsReadOnly="True" AutoGenerateColumns="False" SelectionChanged="selected">绑定了选中事件
    <DataGrid.Columns>
    <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
    <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
    <DataGridTextColumn Header="地址" Binding="{Binding Address}" />
    </DataGrid.Columns>
    </DataGrid>
    <StackPanel Grid.Column="1" Orientation="Vertical">
    <TextBlock FontSize="20" Margin="10">姓名: <Run x:Name="RunName"></Run></TextBlock>
    <TextBlock FontSize="20" Margin="10">年龄:<Run x:Name="RunAge"></Run></TextBlock>
    <TextBlock FontSize="20" Margin="10">地址:<Run x:Name="RunAddress"></Run></TextBlock>
    </StackPanel>
    </Grid>
    c#代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private void selected(Object sender, RoutedEventArgs e)  
    {
    DataGrid dataGrid = sender as DataGrid;
    if (dataGrid == null)
    { return;
    }
    Person person = dataGrid.SelectedItem as Person;
    if (person == null)
    { return;
    }
    this.RunName.Text = person.Name;
    this.RunAge.Text = person.Age + "岁";
    this.RunAddress.Text = person.Address;
    }
    当选中表格某行数据时,会将该数据一并显示到右侧

样式

Window.Resources:css中的style大标签
Style:css中的class
Setter:class中的属性
Property:样式名
value:值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Window.Resources>  
<Style TargetType="Border">
<Setter Property="Background" Value="Aqua"></Setter>
<Setter Property="Height" Value="100"></Setter>
<Setter Property="Width" Value="100"></Setter>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Width" Value="50"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Border>
<TextBlock>dfdf</TextBlock>
</Border>
</StackPanel>
</Grid>

style的属性

  1. x:Key:指定key名,当使用了该属性,只有绑定了该key的标签,才能使用该样式
  2. TargetType:指定使用标签,没指定key时,默认会将该属性指定的标签使用该元素,指定了key,则满足key和TargetType的标签才能使用该样式
  3. BaseOn:继承其他style的样式,根据key绑定

控件模板

子标签指定template属性,通过bangding去绑定值

1
2
3
4
5
6
7
8
9
10
11
12
<Grid>  
<ListBox x:Name="ListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" Background="{Binding Code}"></Border>
<TextBlock Margin="10,0" Text="{Binding Name}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

Code和Name就是后台所传递过来的值,后台传递一个list集合,效果就能实现vue的v-for方式

这种模板方式和vue的模板效果类似,都是通过数据去驱动UI

WPF事件绑定

wpf也有各种事件,和js类似,在标签上面绑定事件以及事件执行的方法

1
2
3
4
5
6
7
8
9
<Grid>  
<StackPanel>
<Slider x:Name="Slider" Margin="5" ValueChanged="RangeBase_OnValueChanged"></Slider>
<TextBlock x:Name="Text1" ></TextBlock>
<TextBlock x:Name="Text2"></TextBlock>
<TextBlock x:Name="Text3"></TextBlock>
<TextBox x:Name="Text4" TextChanged="Text4_OnTextChanged"></TextBox>
</StackPanel>
</Grid>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void RangeBase_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)  
{
Text1.Text = Slider.Value.ToString();
Text2.Text = Slider.Value.ToString();
Text3.Text = Slider.Value.ToString();
}

private void Text4_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (double.TryParse(Text4.Text, out double result))
{
Slider.Value = result;
}
}

c#可以通过x:Name声明的名字直接获取该元素

双向绑定

通过binding实现双向绑定

1
2
<Slider x:Name="Slider" Margin="5"></Slider>
<TextBox x:Name="Text4" Text="{Binding ElementName=Slider,Path=Value}"></TextBox>

elementName指定其他元素的Name,path指定该元素的属性,Mode指定绑定方式
Mode

  1. Default:默认,双向绑定
  2. OneTime:只获取第一次的值
  3. OneWay:单向绑定,当前元素值修改时,不会影响绑定的元素
  4. OneWayToSource:单向绑定,绑定元素修改时,不会影响当前元素

命令

页面元素直接去绑定一个命令,通过该命令去执行传入的方法
命令类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyCommand : ICommand  
{
Action executeAction;

public MyCommand(Action executeAction)
{ this.executeAction = executeAction;
}
public bool CanExecute(object parameter)
{ return true;
}
public void Execute(object parameter)
{ executeAction();
}
public event EventHandler CanExecuteChanged;
}

中间层,执行的方法

1
2
3
4
5
6
7
8
public class MyViewModel  
{
public MyCommand ShowCommand { get; set; }
public MyViewModel()
{ ShowCommand = new MyCommand(show);
} public void show()
{ MessageBox.Show("点击了按钮");
}}

将方法丢入到执行上下文当中

1
2
3
4
5
6
public partial class MainWindow  
{
public MainWindow()
{ InitializeComponent();
this.DataContext = new MyViewModel();
}}

WPF通知

在事件执行的方法中修改值,不会反应到UI上

![](https://zhaoci.asia:9001/myimages/img/Pasted image 20240717102208.png)
点击了按钮,但是UI上面的文字没被变更
将方法类继承INotifyPropertyChanged接口
添加一个属性public event PropertyChangedEventHandler PropertyChanged;
在使用到页面属性的地方调用该对象的方法

1
2
3
4
5
6
7
8
public string Name  
{
get { return name; }
set
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}}

![](https://zhaoci.asia:9001/myimages/img/Pasted image 20240717105333.png)

静态资源和动态资源

StaticResource:静态资源绑定,第一次加载的时候样式绑定,后续不会动态变更
DynamicResource:动态资源绑定,后续可以通过代码将资源继续变更