示例版本在Prism Dryloc框架上示例的
搭建框架介绍
- 1 在程序中下载Nuget包Prism.DryIoc
- 2 将App.xaml 和App.cs文件改为以下示例
<prism:PrismApplication
x:Class="WpfApp4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources />
</prism:PrismApplication>
using Prism.DryIoc;
using Prism.Ioc;
using System.Windows;
using WpfApp4.ViewModel;
namespace WpfApp4
{
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainWindow,Class1>();
}
}
}
- 3 绑定上下文 view 绑定到ViewModel 两种方法
1 创建自定义控件类
知识:创建自定义控件类,你可以理解为创建一个和Button一样的类我们需要继承一个控件(不一定要继承示例的这个类,其他类也可以)
using System.Windows.Controls;
namespace WpfApp4
{
public class MyControl : ContentControl
{
}
}
1.1绘制自定义控件外观
上面继承了 : ContentControl类这个MyControl就是我们的控件名称了,下一步给他创建一个外观吧。创建资源字典 名称为“Dictionary1”
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:con="clr-namespace:WpfApp4">
<Style TargetType="con:MyControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="con:MyControl">
<Border
x:Name="border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<StackPanel>
<Rectangle
Width="100"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="150"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="100"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="50"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="25"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="12.5"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
<Rectangle
Width="6.25"
Height="30"
Fill="#a6a6a6"
Stroke="#3b3b3b" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
在App中引用当前资源
<prism:PrismApplication
x:Class="WpfApp4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>
在前端引用
<Window
x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp4"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid >
<local:MyControl/>
</Grid>
</Window>
效果图:
1.2添加自定义控件的依赖属性
这样我们就算创建了一个自定义控件,但我们如果想控制他的大小我们就需要给控件添加一些,依赖属性。添加依赖属性:注释在代码里!!!
using System.Windows;
using System.Windows.Controls;
namespace WpfApp4
{
public class MyControl : ContentControl
{
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty = DependencyProperty.Register(nameof(X), typeof(double), typeof(MainWindowViewModel), new PropertyMetadata(0.0, Change));
private static void Change(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//当前 X 值 发生更改时触发当前方法
}
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public static readonly DependencyProperty YProperty = DependencyProperty.Register(nameof(Y), typeof(double), typeof(MainWindowViewModel), new PropertyMetadata(0.0));
//解释: nameof(Y)是基于哪一个属性 typeof(double):当前属性的数据类型 typeof(MainWindowViewModel)当前属性属于哪一个类 new PropertyMetadata(0.0)); 给当前依赖属性的默认值
//取命注意 DependencyProperty 类型的名称必须Property结尾
}
}
修改一下资源字典的绑定 (只修改了 第13行)
<StackPanel Width="{TemplateBinding X}" Height="{TemplateBinding Y}">
在前端给属性赋值上,就发现大小可以自定义了
<Grid >
<local:MyControl X="200" Y="250"/>
</Grid>
1.3当前效果图
1.4 添加自定义控件的事件
1 修改一下上面的MyControl类 在类中的第8行 和Change方法中调用事件
using System.Windows;
using System.Windows.Controls;
namespace WpfApp4
{
public class MyControl : ContentControl
{
public event RoutedEventHandler MyCustomEvent;
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty = DependencyProperty.Register(nameof(X), typeof(double), typeof(MyControl), new PropertyMetadata(0.0, Change));
//当前 X 值 发生更改时触发当前方法
private static void Change(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//当值发生修改当前事件触发
(d as MyControl).MyCustomEvent?.Invoke(d, new RoutedEventArgs());
}
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public static readonly DependencyProperty YProperty = DependencyProperty.Register(nameof(Y), typeof(double), typeof(MyControl), new PropertyMetadata(0.0));
//解释: nameof(Y)是基于哪一个属性 typeof(double):当前属性的数据类型 typeof(MyControl)当前属性属于哪一个类 new PropertyMetadata(0.0)); 给当前依赖属性的默认值
//取命注意 DependencyProperty 类型的名称必须Property结尾
}
}
2 在前端绑定当前事件触发到的Icommand
<Window
x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:WpfApp4"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
Title="MainWindow"
Width="800"
Height="450"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<Grid>
<local:MyControl X="200" Y="250">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MyCustomEvent">
<prism:InvokeCommandAction Command="{Binding MyProperty}" />
<!--绑定触发事件的方法-->
</i:EventTrigger>
</i:Interaction.Triggers>
s
</local:MyControl>
</Grid>
</Window>
3 在视图对应的ViewModel中添加绑定的命令以及触发的方法
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfApp4
{
public class MainWindowViewModel:BindableBase
{
public MainWindowViewModel()
{
}
public ICommand MyProperty { get => new DelegateCommand<object>(L); }
private void L(object s)
{
//触发到的方法
}
}
}
效果就是每修改X的值,就会触发当前的方法,但怎么传递参数呢?
1.5 创建Icommand类型的依赖属性
icommand能解决什么问题?在我们想触发的位置触发当前命令,并传递参数。
1 第一步在MyControl中创建Icommand类型的属性
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApp4
{
public class MyControl : ContentControl
{
public event RoutedEventHandler MyCustomEvent;
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty = DependencyProperty.Register(nameof(X), typeof(double), typeof(MyControl), new PropertyMetadata(0.0, Change));
//当前 X 值 发生更改时触发当前方法
private static void Change(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//当值发生修改当前事件触发
//(d as MyControl).MyCustomEvent?.Invoke(d, new RoutedEventArgs());
//command 触发命令 Execute方法 d为传递的参数
(d as MyControl).Command?.Execute(d);
}
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public static readonly DependencyProperty YProperty = DependencyProperty.Register(nameof(Y), typeof(double), typeof(MyControl), new PropertyMetadata(0.0));
//解释: nameof(Y)是基于哪一个属性 typeof(double):当前属性的数据类型 typeof(MyControl)当前属性属于哪一个类 new PropertyMetadata(0.0)); 给当前依赖属性的默认值
//取命注意 DependencyProperty 类型的名称必须Property结尾
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( "Command", typeof(ICommand), typeof(MyControl), new PropertyMetadata(null));
public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
}
}
2 第二步在前端绑定触发命令的方法
<Window
x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:WpfApp4"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
Title="MainWindow"
Width="800"
Height="450"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<Grid>
<local:MyControl
Command="{Binding MyProperty}"
X="200"
Y="250" />
</Grid>
</Window>
3 在视图中的ViewModel中 写下触发方法
using Prism.Commands;
using Prism.Mvvm;
using System.Windows.Input;
namespace WpfApp4
{
public class MainWindowViewModel:BindableBase
{
public MainWindowViewModel()
{
}
public ICommand MyProperty { get => new DelegateCommand<object>(L); }
private void L(object s)
{
//触发到的方法
}
}
}
1.6 创建自定义控件的事件
在MyControl 类中添加以下代码,注册一个鼠标点击触发事件,如果你想传递什么参数,可以参考1.7
//protected 关键字受保护的 override 重写
protected override void OnMouseDown(MouseButtonEventArgs e)
{
//当前是鼠标点击控件就触发事件
}
1.7 创建自定义控件的Command
创建自定义控件的command 就是实现各种事件的触发回调 ,传递参数
情景:在值发生更改时,触发command绑定的方法,并传递当前对象到绑定的方法当中作为参数
1 先在 MyControl 类中添加如下代码
public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( "Command", typeof(ICommand), typeof(MyControl), new PropertyMetadata(null));
2 在调用界面给command绑定方法
<Grid>
<Button Height="20" VerticalAlignment="Bottom" />
<local:MyControl
Command="{Binding MyProperty}"
X="200"
Y="250" />
</Grid>
绑定到的ViewModel 中添加
public class MainWindowViewModel:BindableBase
{
public MainWindowViewModel()
{
}
public ICommand MyProperty { get => new DelegateCommand<object>(L); }
private void L(object s)
{
//触发到的方法
}
}
3 在想触发绑定的命令处,调用命令。
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty = DependencyProperty.Register(nameof(X), typeof(double), typeof(MyControl), new PropertyMetadata(0.0, Change));
//当前 X 值 发生更改时触发当前方法
private static void Change(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//command 触发命令 Execute方法 d为传递的参数
(d as MyControl).Command?.Execute(d);
}
4 运行后效果: