WPF的前世今生
阅读原文时间:2023年08月15日阅读:1

1、WPF的布局

WPF的布局分为相对定位和绝对定位两种。

绝对定位一般用Canvas

相对定位一般用Grid、StackPanel、DockPanel、WrapPanel

2、MVVM模式是什么

MVVM就是Model View ViewModel

Model层就是数据层,你可以把它理解成实体层,一般情况下,只要不和服务端挂钩或者小型项目,写一个实体类就行了,和服务端挂钩,或者大型项目加入了DTO,小项目返回原生对象就行了,它此时是有状态的,要和数据库挂钩,比如你用到SqlSugar,你这个实体类就不能单独的继承BindableBase了

View就是视图,你写的Xaml文件用来展示前端界面的,还有就是你对绑定、事件的声明

ViewModel层就是业务处理的,用来处理你前面View的所有声明,通常也会监听View层,比如ViewModel层更新,View层更新

优点就是降低代码耦合,提高重用性

3、Xaml文件

一般情况下,你可以使用Xaml文件来写WPF的前端页面(但是不一定,后文提到)

Xaml文件,你可以理解为Xml文件的扩展,

通常,我们Xml文件是这样书写的

<object>
  <Animal>
    <Cat></Cat>
  </Animal>
</object>

在Xaml文件中格式也是一样的。

<Window
    x:Class="WPFSample.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:custom="clr-namespace:WPFSample.Controls"
    xmlns:views="clr-namespace:WPFSample.Views"
    Title="How to create a WPF"
    Width="500"
    Height="500">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
    </Grid>
</Window>

在我们普通的书写代码中,不管是java还是C#,或者是Python,

他们的.cs、.java 、.py文件上方是

using xxx;

import xxx;

这个using和import就在Xaml文件中使用xmlns表示。

我在写详细一点

你的MainViewModel要应用一个Student类

那么你可以这样书写

using WPFSample;
using WPFSample.Student;
public class MainViewModel
{
    private Student Stus{get;set;}
}

那么在Xaml文件中你可以这样做

<Window x:class="WPFSample"
        xmlns:stu="WPFSample.Student">

</Window>

stu是随便取得名字,方便在下面使用

现在我们来编写一个简单的页面

如果你了解Html或者一点Vue,那么你就能更好的理解了,不了解没关系,我可以详细的为你解答

1、你首先使用VS创建一个WPF的程序,并且你运行了它,它打开后是一个弹窗,差不多和一个QQ的登录界面一样大小。

2、你可以写一个Button控件,并且描述了它的长宽,以及它的内容

<Button Width="200" Height="25" Content="按钮"/>

3、运行代码,你可以发现,弹窗中有了按钮

4、现在你想复刻QQ的界面

你这样写了

<TextBlick Text="登录"/>
<TextBox Width="200"/>
<Button Width="80"/>

你发现错落有致,没有达到你想要的效果

那么,就要用到WPF的布局了

<Grid Margin="100,50,100,50">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                FontSize="30"
                Text="{Binding appData.SystemName}" />

            <StackPanel Grid.Row="1" Orientation="Horizontal">
                <TextBlock
                    Width="60"
                    Margin="50,0,0,0"
                    VerticalAlignment="Center"
                    FontSize="18"
                    Text="用户名:" />
                <TextBox
                    Width="200"
                    Margin="10,0,0,0"
                    VerticalAlignment="Center"
                    mah:TextBoxHelper.Watermark="请输入用户名"
                    mah:TextBoxHelper.ClearTextButton="True"
                    Text="{Binding appData.CurrentUser.Name}" />
            </StackPanel>

            <StackPanel Grid.Row="2" Orientation="Horizontal">
                <TextBlock
                    Width="60"
                    Margin="50,0,0,0"
                    VerticalAlignment="Center"
                    FontSize="18"
                    Text="密码:" />
                <PasswordBox
                    Width="200"
                    Margin="10,0,0,0"
                    VerticalAlignment="Center"
                    mah:TextBoxHelper.ClearTextButton="True"
                    mah:TextBoxHelper.Watermark="请输入密码"
                     converter:PasswordBoxHelper.Attach="True"
                    converter:PasswordBoxHelper.Password="{Binding appData.CurrentUser.Password,Mode=TwoWay}" />

                <!--<TextBox
                    Width="200"
                    Margin="10,0,0,0"
                    VerticalAlignment="Center"
                    Text="{Binding appData.CurrentUser.Password}" />-->
            </StackPanel>

            <StackPanel
                Grid.Row="3"
                Margin="40,0,0,0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <Button
                    Width="80"
                    Command="{Binding LoginCommand}"
                    CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=mah:MetroWindow}}"
                    Content="登录"
                    IsDefault="True" />
                <Button
                    Width="80"
                    Margin="40,0,0,0"
                    Command="{Binding CancelCommand}"
                    Content="取消"
                    IsCancel="True" />
            </StackPanel>
</Grid>

我现在讲解一下,这段简单的代码,你把Grid当作一个框,一间房,

你知道Row是英文行、排的意思,那么

              <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

这段代码就是把你刚才打开的弹窗分成了4层

程序中是从0开始的,不是1,

所以你的第一行写了TextBlock。