1、WPF基础
在开始之前首先了解一下什么是数据驱动和事件驱动
首先事件驱动就是我们习已为常的Click类型的事件 这种就叫做事件驱动
数据驱动
就是通过我们定义的方法void去进行进行绑定 然后实现效果
1.1布局
常用是Gird布局 <RowDefinition/> 行
<ColumnDefinition/> 列
或者是:StackPanel布局 (水平垂直)
**//一个关键点是:前端里面百分比的宽高 在WPF里面用的是*号 ** <RowDefinition Height="0.5*"/>
1.2样式
WPF中的样式跟CSS是差不多的只不过是写法不同
其中 TargetType是样式目标
x:Key是相当于Css中的 id一样
对控件进行样式操控是Setter(属性) 其中 Property是要进行修改什么样式
到使用样式的时候StaticResource:样式的名称=>x:Key
BasedOn: 就是继承的意思
<Window.Resources>
<Style TargetType="Button" x:Key="All">
<Setter Property="FontSize" Value="58"/>
<Setter Property="Background" Value="Red"/>
<Setter Property="Content" Value="Button"/>
</Style>
<Style TargetType="Button" x:Key="ButtonStyle" BasedOn="{StaticResource All}"/>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
</StackPanel>
</Grid>
像CSS一样外置文件的样式,就需要去添加资源字典(xaml)
<Application x:Class="WpfApp2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp2"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WpfApp2;component/BaseButtonStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
1.3数据模板
其实没什么相当于就是 把后台数据绑定到控件上面看代码就知道了
通过Binding 数据的名称
达到数据模板的方式
<ListBox.ItemTemplate>
是这个控件的属性
<DataTemplate>
:DataTemplate
用于定义单个数据项的显示外观。
然后通过把数据绑定在ItemsSource
上这才能正确显示在ListBox中
<Grid>
<ListBox x:Name="list">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Width="10" Height="10" Background="{Binding Coler}"/>
<TextBlock Margin="10,0" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
cs文件
public MainWindow()
{
InitializeComponent();
List<Code> test = new List<Code> ();
test.Add(new Code() { Coler = "#DCDCDC", Name = "OldLace" });
test.Add(new Code() { Coler = "#FFDAB9", Name = "Gainsboro" });
test.Add(new Code() { Coler = "#F0FFFF", Name = "WhiteSmoke" });
test.Add(new Code() { Coler = "#E6E6FA", Name = "tGhostWhite" });
test.Add(new Code() { Coler = "#FA8072", Name = "tSalmon" });
list.ItemsSource = test;
}
}
class Code
{
public string Coler { get; set; }
public string Name { get; set; }
}
1.4绑定
绑定(相当于Vue中的v-model)
绑定的模式有四种:
默认:OneWay 单项绑定, TwoWay 双向绑定,OneTime 一次性绑定 一次过后不再更新,OneWayToSource: 单项的绑定 虽然数据会变化但是不会反馈到目标的属性上
基本的绑定:
首先我定义出2个全局对象
public string Username { get;set; }
public string Password { get;set; }
然后我的控件去绑定这两个全局对象
<TextBox Margin="2" Text="{Binding Username}"/>
<TextBox Text="{Binding Password}" Margin="2"/>
最为关键的一句:this.DataContext = this;
//将窗口实例本身作为数据上下文(DataContext)设置给窗口这样窗口中的控件就可以直接绑定到窗口的属性或命令上
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public string Username { get;set; }
public string Password { get;set; }
private void btn1(object sender, RoutedEventArgs e)
{
if(Username == "ktton" && Password == "1234")
{
//MessageBox.Show("登录成功");
Index index = new Index();
index.Show();
this.Hide();
}
else
{
MessageBox.Show("密码或者用户名不正确");
}
}
Binding ElementName="绑定到谁身上",Path="绑定到这个控件身上的那个属性"
<Grid>
<StackPanel>
<Slider x:Name="slider" Margin="5" />
<TextBox Text="{Binding ElementName=slider,Path=Value}" />
<TextBox Text="{Binding ElementName=slider,Path=Value}" />
<TextBox Text="{Binding ElementName=slider,Path=Value}" />
</StackPanel>
</Grid
4.1绑定(属性通知到页面)
就拿上面的登录、注册来做例子
当密码或者账号错误的时候 弹出错误窗口之后把user和password清空
正常思维写法是: else { MessageBox.Show("密码或者用户名不正确"); Username =""; Password=""; } //但是这样是无法让窗口页面上进行清空的改变所以就需要属性通知(比较繁琐 后面的Prism框架就没那么麻烦)
1.5命令ICommand(多用于交互)
个人感觉命令好麻烦(数据驱动)
ICommand
是定义命令的接口,它包含两个方法:CanExecute
和 Execute
,以及一个事件 CanExecuteChanged
其中CanExecute
是用于这个命令是否可用
Execute
是用于执行命令。当命令可用时,WPF 会自动调用 Execute
方法来执行命令定义的操作
MyICommand.cs
class MyICommand : ICommand
{
Action ButClick { get; set; }
public MyICommand(Action action )
{
ButClick = action;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
ButClick();
}
}
MainWindow.cs
public MainWindow()
{
InitializeComponent();
this.DataContext = new ButtonMain(); ;
}
ButtonMain.cs
class ButtonMain
{
public ButtonMain()
{
ShowBtn = new MyICommand(Show);
}
public MyICommand ShowBtn { get; set; }
//这里写事件
public void Show()
{
MessageBox.Show("只是些许风霜罢了");
}
}
2、Prism框架
使用Prism框架首相要在NuGet中添加 Prism.dryioc
这个包
安装好之后首先修改一下
App.cs
public partial class App : PrismApplication
//修改完之后会出现说App没有实现一些抽象类的接口 让他自己生成一下就可以了
//Application
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
//第一个抽象类是用来获取一个窗口作为主窗口
//其中Container是Prism提供的一个容器
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//这里是用于依赖注入、接口、实现类
}
}
App.xaml
//修改一下前缀名 修改完之后添加一下 xmlns:prism="http://prismlibrary.com/"就可以了
<prism:PrismApplication x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
==> xmlns:prism="http://prismlibrary.com/"
StartupUri="MainWindow.xaml"> //记住要把这一句删除不然的话会一开始就弹出2个窗口
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
2.1Prism中的通知更新
之前lNotifyPropertyChanged(通知更新)这个写起来很繁琐,但是运用到框架上就没那么麻烦了
首先Prism中的BindableBase这是一个相当于lNotifyPropertyChanged的一个封装 一开始通过继承之后就可以免去很多繁琐的工作了
class MainViewModel :BindableBase
{
//上面这个继承BindableBase相当于就是 WPF中的通知修改
private string _title;
public string title
{
get { return _title; }
//在这里set中我们不能直接使用 =value 这样是得不到效果的
//需要通过BindableBase提供的SetProperty方法这个方法封装了设置和通知过程
//SetProperty(参数1, 参数2) 参数1是要更新的属性的引用 参数2是新的值 如果新值与旧值不同那么会立刻触发属性更新通知
//通知UI元素进行更新
//set { _title = value; }
set { SetProperty(ref _title, value); }
}
}