WPF学习历程

351 阅读2分钟

一、Panel布局

  1. Grid 网格布局,以表格形式布局元素
  2. Stack栈布局,元素按一行或一列排布
  3. Warp 环绕布局,元素按一行或一列排布,到达边界时,自动换行
  4. Dock 停靠布局,默认情况下,最后一个元素会填充剩余空间,LastChildFill
  5. 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

属性值改变通知

image.png 当后端代码改变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 特性是 不需要传递属性名,会自动查找。

image.png model层继承ViewModelBase类,属性改变时,调用OnPropertyChanged方法即可。