(三)登录模块实现
1.整改login页面加载方式
1.1符合MVVM
用事件触发器绑定命令来代替直接执行load事件绑定的方法
- 引入
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" - 删掉load事件,新增behaviors触发器
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
- MainWindow中方法删掉,在view model中
![image]()
- 导航区域名字最好把页面名称都封装起来调用
![image]()
1.2 prism框架服务的不同使用方式
也可以不在构造函数依赖注入,采取下面那种方式

但这种方法违反了IOC容器的使用思想
2.用户登录
2.1 创建实体类user

2.2 前台页面的绑定

2.3 ReactiveObject
ReactiveUI是一个高级的、可组合的、功能反应式的模型-视图-视图模型(MVVM)框架,适用于所有.NET平台。它受到了函数式反应式编程范式的启发。
reactiveui手册
ReactiveObject可以通过注解实现通知更新的功能

2.4 验证通过后的页面跳转
通过事件聚合器实现
- 在share模块添加事件
![image]()
- 在验证通过后发布一个事件
![image]()
- 在加载主窗体load方法中订阅事件,生成回调函数
![image]()
- 当这个事件触发后运行这个回调函数
private void OnLogined(CurrentUser user)
{
//加载主界面
PrismProvider.ModuleManager.LoadModule(ModuleNames.ApplicationMainModule);//这里是仅仅传递了字符串,但是这个类继承了imodule,会通过名称找到这个类
//导航到主区域
PrismProvider.RegionManager.RequestNavigate(RegionNames.MainRegion, ViewNames.MainView);
}
3.自定义控件的写法
当验证信息错误时,弹出提示,然后慢慢自己消失
3.1 新建wpf用户控件
Popup 控件提供一种在单独窗口中显示内容的方法,该窗口相对于指定元素或屏幕坐标在当前应用程序窗口上浮动。
popup介绍
- 用户控件的修改
![image]()
![image]()
文本绑定:
Text="{Binding Path=Message,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PopupBox},UpdateSourceTrigger=PropertyChanged}"
- 有2个属性
public new double Opacity//new 添加了 即隐藏了uielement中的透明度
{
get { return (double)GetValue(OpacityProperty); }
set { SetValue(OpacityProperty, value); }
}
// 设置亮度1.0
public static new readonly DependencyProperty OpacityProperty =
DependencyProperty.Register("Opacity", typeof(double), typeof(PopupBox), new PropertyMetadata(1.0,new PropertyChangedCallback(OnOpacityPropertyChangedCallback)));
/// <summary>
/// 上面属性更新的回调函数
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void OnOpacityPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is PopupBox box)) return;
if (!(e.NewValue is double v)) return;
box.border.Opacity = v;//赋值新的透明度
}
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
// Using a DependencyProperty as the backing store for Message. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(PopupBox), new PropertyMetadata(string.Empty));
- d is PopupBox box判断并赋值
- 弹出方法(时间间隔是传入的)
public static void Show(string message,Window owner=null,int seconds = 1)
{
try
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
if (owner != null)
{
owner = Application.Current.MainWindow;
}
dialog.Message = message;
dialog.PlacementTarget = owner;//投放目标窗体
dialog.Placement = PlacementMode.Center;//位置居中
dialog.StaysOpen = true;//Popup控件会一直显示,直到显式地将IsOpen属性设置为False。如果将Popup.StaysOpen属性设置为False,当用户在其他地方单击鼠标时,Popup控件就会消失。
dialog.AllowsTransparency = true;//该值指示窗口的工作区是否支持透明度
dialog.VerticalOffset = owner.ActualHeight / 3;//垂直偏移,目标窗体的1/3
dialog.Opacity = 0.9;//透明度
dialog.IsOpen = true;//是否打开
//dialog显示后一秒慢慢消失
timer.Tick -= Timer_Tick;
timer.Tick += Timer_Tick;
timer.Interval = new TimeSpan(0, 0, seconds);
timer.Start();
}));
}
catch(Exception ex)
{
}
}
3.2 Dispatcher
dispatcher类
Wpf中Dispatcher.Invoke和Dispatcher.BeginInvoke的区别
new Thread(()=> {
Application.Current.Dispatcher.BeginInvoke(new Action(() => {
while (true)
{
Thread.Sleep(1000);
}
}), null);
Console.WriteLine("test");
}).Start();
这段代码,会在控制台打印test,然后界面会一直卡住。界面卡住,说明while循环是在ui线程执行的,能够打印test,说明在执行Application.Current.Dispatcher.BeginInvoke时并没有阻塞当前界面,如果把BeginInvoke改成Invoke,那么test将不会被打印,说明Invoke方法的逻辑是把委托交给ui线程执行,并阻塞当前线程,直到委托结束。而BeginInvoke方法则首先新开一个线程,那新开的线程,再将委托交给ui线程处理。注意,最终执行委托的线程都是ui线程。所以,BeginInvoke由于有个新开线程的过程,不会阻塞当前线程。但仍然会阻塞界面。
3.3 事件控制透明度
private static void Timer_Tick(object sender, EventArgs e)
{
timer.Stop();
Task.Run(() =>
{
try
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(5);
if (Application.Current == null) return; //Application.Current==>shell.app
Application.Current.Dispatcher.Invoke(() =>
{
dialog.Opacity -= 0.01;
});
}
//透明度减完,把显示关闭,信息清空
Application.Current.Dispatcher.Invoke(() =>
{
dialog.IsOpen = false;
dialog.Message=string.Empty;
});
}
catch (Exception ex)
{
}
});
}
3.4 使用










浙公网安备 33010602011771号