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;} }
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。