文章目录
前言
我学了HandyControl的基础使用,但是发现HandyControl 封装了基础的消息提示,但是没有封装基础的交互逻辑。可能是因为我写了Uniapp,我知道封装了基础的交互其实一般就够用了。
Uniapp 界面交互反馈
我现在觉得,代码要低耦合一点,每个模块都纯粹一点,这一次我就不添加Nlog日志打印了。
仓库地址
因为最后代码比较多,我就放在仓库里了
gclove2000 / WPF HandyControl 交互
相关链接
HandyControl Github地址
HandyControl 官方中文文档
WPF-UI HandyControl 简单介绍
WPF-UI HandyControl 控件简单实战+IconPacks矢量图导入
WPF 消息日志打印帮助类:HandyControl+NLog+彩色控制台打印+全局异常捕捉
HandyControl使用
HandyControl Dialog 对话框
顺便再装一个CommunityToolkit.MVVM
官方Demo使用
<Borderx:Class="HandyControlDemo.UserControl.TextDialog"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"xmlns:ex="clr-namespace:HandyControlDemo.Tools.Extension"xmlns:hc="https://handyorg.github.io/handycontrol"CornerRadius="10"Width="400"Height="247"Background="{DynamicResource RegionBrush}"><hc:SimplePanel><TextBlockStyle="{StaticResource TextBlockLargeBold}"Text="{ex:Lang Key={x:Static langs:LangKeys.PleaseWait}}"/><ButtonWidth="22"Height="22"Command="hc:ControlCommands.Close"Style="{StaticResource ButtonIcon}"Foreground="{DynamicResource PrimaryBrush}"hc:IconElement.Geometry="{StaticResource ErrorGeometry}"Padding="0"HorizontalAlignment="Right"VerticalAlignment="Top"Margin="0,4,4,0"/></hc:SimplePanel></Border>
namespaceHandyControlDemo.UserControl{publicpartialclassTextDialog{publicTextDialog(){InitializeComponent();}}}
我现在才知道,原来想要弹窗的边框为圆角,要将UserControl改为Border
代码调用
按钮加个显示就可以了
Dialog.Show(new TextDialogView());
使用效果
异步回调
虽然HandyControl实现了这个功能,但是文档写的很少
没办法继续下去了,只能进代码里面看看了
代码实现
TextDialogView.xaml
<Borderx:Class="WpfApp1.Views.TextDialogView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfApp1.Views"xmlns:hc="https://handyorg.github.io/handycontrol"xmlns:ViewModels="clr-namespace:WpfApp1.ViewModels"Width="400"Height="247"CornerRadius="20"Background="{DynamicResource RegionBrush}"mc:Ignorable="d"><Border.DataContext><ViewModels:TextDialogViewModel/></Border.DataContext><hc:SimplePanel><StackPanelVerticalAlignment="Center"><TextBlockStyle="{StaticResource TextBlockLargeBold}"Text="消息提示"/><TextBoxText="{Binding TestContent}"hc:InfoElement.Placeholder="请输入文本"Style="{StaticResource TextBoxExtend}"/></StackPanel><ButtonWidth="22"Height="22"Command="hc:ControlCommands.Close"Style="{StaticResource ButtonIcon}"Foreground="{DynamicResource PrimaryBrush}"hc:IconElement.Geometry="{StaticResource ErrorGeometry}"Padding="0"HorizontalAlignment="Right"VerticalAlignment="Top"Margin="0,4,4,0"/></hc:SimplePanel></Border>
TextDialogView.xaml.cs
publicpartialclassTextDialogViewModel:ObservableObject,IDialogResultable<string>{[ObservableProperty]privatestring testContent ="";publicTextDialogViewModel(){}/// <summary>/// 这个是回调的结果/// </summary>publicstring Result
{get=> TestContent;set{
TestContent =value;}}/// <summary>/// 这个暂时我不知道有啥用/// </summary>publicAction CloseAction {get;set;}}
方法调用
publicRelayCommand ShowTextDialogBtn =>newRelayCommand(async()=>awaitShowText());privateasyncTaskShowText(){var res =await Dialog.Show<TextDialogView>().Initialize<TextDialogViewModel>(vm => vm.TestContent ="").GetResultAsync<string>();
MessageBox.Show(res);}
显示结果
取消弹窗
HandyControl给了我们两个取消弹窗的方式
方法1:直接取消
方法2:接口调用
C#调用线程必须为 STA,因为许多 UI 组件都需要。
如果出现了以下问题,要注意窗口线程是不能开启新的线程的
C#调用线程必须为 STA,因为许多 UI 组件都需要。
遮罩点击
我找了一天了,还是没找到方法
【WPF】查找父/子控件(元素、节点)
How could I close a Interactive Dialog when clicking outside #1272
哎,看起来还是得用点奇技淫巧
设计思路
#mermaid-svg-wqD6VhEqzIEe0UQH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .error-icon{fill:#552222;}#mermaid-svg-wqD6VhEqzIEe0UQH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wqD6VhEqzIEe0UQH .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-wqD6VhEqzIEe0UQH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wqD6VhEqzIEe0UQH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wqD6VhEqzIEe0UQH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wqD6VhEqzIEe0UQH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wqD6VhEqzIEe0UQH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wqD6VhEqzIEe0UQH .marker.cross{stroke:#333333;}#mermaid-svg-wqD6VhEqzIEe0UQH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wqD6VhEqzIEe0UQH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .cluster-label text{fill:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .cluster-label span{color:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .label text,#mermaid-svg-wqD6VhEqzIEe0UQH span{fill:#333;color:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .node rect,#mermaid-svg-wqD6VhEqzIEe0UQH .node circle,#mermaid-svg-wqD6VhEqzIEe0UQH .node ellipse,#mermaid-svg-wqD6VhEqzIEe0UQH .node polygon,#mermaid-svg-wqD6VhEqzIEe0UQH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wqD6VhEqzIEe0UQH .node .label{text-align:center;}#mermaid-svg-wqD6VhEqzIEe0UQH .node.clickable{cursor:pointer;}#mermaid-svg-wqD6VhEqzIEe0UQH .arrowheadPath{fill:#333333;}#mermaid-svg-wqD6VhEqzIEe0UQH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wqD6VhEqzIEe0UQH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wqD6VhEqzIEe0UQH .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-wqD6VhEqzIEe0UQH .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-wqD6VhEqzIEe0UQH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wqD6VhEqzIEe0UQH .cluster text{fill:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH .cluster span{color:#333;}#mermaid-svg-wqD6VhEqzIEe0UQH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wqD6VhEqzIEe0UQH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
DialogView
点击
IsClick为True
松开
IsClick为False
移出控件
Dialog触发Click
背景点击
额,可能说的比较复杂。简单来说就是背景点击的时候,对话框没点击,那就是外侧点击了。
代码逻辑
TextDialogView.xaml
<Borderx:Class="WpfApp1.Views.TextDialogView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfApp1.Views"xmlns:hc="https://handyorg.github.io/handycontrol"xmlns:ViewModels="clr-namespace:WpfApp1.ViewModels"Width="400"Height="247"CornerRadius="20"Background="{DynamicResource RegionBrush}"mc:Ignorable="d"><Border.DataContext><ViewModels:TextDialogViewModel/></Border.DataContext><hc:SimplePanel><StackPanelVerticalAlignment="Center"><TextBlockStyle="{StaticResource TextBlockLargeBold}"Text="消息提示"/><TextBoxText="{Binding TestContent}"hc:InfoElement.Placeholder="请输入文本"Style="{StaticResource TextBoxExtend}"/></StackPanel><ButtonWidth="22"Height="22"Command="hc:ControlCommands.Close"Style="{StaticResource ButtonIcon}"Foreground="{DynamicResource PrimaryBrush}"hc:IconElement.Geometry="{StaticResource ErrorGeometry}"Padding="0"HorizontalAlignment="Right"VerticalAlignment="Top"Margin="0,4,4,0"/></hc:SimplePanel></Border>
TextDialogView.xaml.cs
/// <summary>/// TextDialogView.xaml 的交互逻辑/// </summary>publicpartialclassTextDialogView{publicTextDialogView(){InitializeComponent();//将本身指针传给ViewModel(this.DataContext asTextDialogViewModel).TextDialogView =this;}}
TextDialogViewModel
publicpartialclassTextDialogViewModel:ObservableObject,IDialogResultable<string>{[ObservableProperty]privatestring testContent ="";publicbool IsClick {get;set;}privateTextDialogView textDialogView;/// <summary>/// 拿到TextDialogView的时候,添加点击函数/// </summary>publicTextDialogView TextDialogView
{get=> textDialogView;set{
textDialogView =value;
textDialogView.MouseLeftButtonDown +=(sender, e)=>{
IsClick =true;};
textDialogView.MouseLeftButtonUp +=(sender, e)=>{
IsClick =false;};
textDialogView.MouseLeave +=(sender, e)=>{
IsClick =false;};}}publicTextDialogViewModel(){}/// <summary>/// 这个是回调的结果/// </summary>publicstring Result
{get=> TestContent;set{
TestContent =value;}}/// <summary>/// 这个暂时我不知道有啥用/// </summary>publicAction CloseAction {get;set;}}
运行结果
方法设计
Uniapp 将界面交互分为
- 消息提示
- 加载
- 输入框
- 列表选择
这个其实已经包含了大部分的交互内容了,如果想自定义,可以自己去研究一下。由于HandyControl已经封装了消息控件了,拿我们就封装另外三个功能了。
代码封装
由于代码比较复杂,我这里就放我的设计思路了。
我把详细的代码放在Gtiee仓库里面了
gclove2000 / WPF HandyControl 交互
静态方法
我把交互改成了静态的方法。
运行结果
版权归原作者 龙中舞王 所有, 如有侵权,请联系我们删除。