WPF HandyControl 界面交互反馈:对话框+加载框+列表选择

文章目录

前言

我学了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使用

xml 复制代码
<Border x: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>
        <TextBlock Style="{StaticResource TextBlockLargeBold}" Text="{ex:Lang Key={x:Static langs:LangKeys.PleaseWait}}"/>
        <Button Width="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>
csharp 复制代码
namespace HandyControlDemo.UserControl
{
    public partial class TextDialog
    {
        public TextDialog()
        {
            InitializeComponent();
        }
    }
}

我现在才知道,原来想要弹窗的边框为圆角,要将UserControl改为Border

代码调用

按钮加个显示就可以了

复制代码
Dialog.Show(new TextDialogView());

使用效果

异步回调

虽然HandyControl实现了这个功能,但是文档写的很少

没办法继续下去了,只能进代码里面看看了


代码实现

TextDialogView.xaml
xml 复制代码
<Border x: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>
        <StackPanel VerticalAlignment="Center">
            <TextBlock Style="{StaticResource TextBlockLargeBold}"
                       Text="消息提示" />
            <TextBox Text="{Binding TestContent}"
                     hc:InfoElement.Placeholder="请输入文本"
                     Style="{StaticResource TextBoxExtend}"  />
        </StackPanel>

        <Button Width="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
csharp 复制代码
 public partial class TextDialogViewModel : ObservableObject, IDialogResultable<string>
{

    [ObservableProperty]
    private string testContent = "";

    public TextDialogViewModel()
    {

    }

    /// <summary>
    /// 这个是回调的结果
    /// </summary>
    public string Result
    {
        get => TestContent; set
        {
            TestContent = value;
        }
    }
    /// <summary>
    /// 这个暂时我不知道有啥用
    /// </summary>
    public Action CloseAction { get; set; }
}
方法调用
csharp 复制代码
        public RelayCommand ShowTextDialogBtn => new RelayCommand(async()=> await ShowText() );


        private async Task ShowText()
        {
            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

哎,看起来还是得用点奇技淫巧

设计思路

DialogView 点击 IsClick为True 松开 IsClick为False 移出控件 Dialog触发Click 背景点击

额,可能说的比较复杂。简单来说就是背景点击的时候,对话框没点击,那就是外侧点击了。

代码逻辑

TextDialogView.xaml
xml 复制代码
<Border x: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>
        <StackPanel VerticalAlignment="Center">
            <TextBlock Style="{StaticResource TextBlockLargeBold}"
                       Text="消息提示" />
            <TextBox Text="{Binding TestContent}"
                     hc:InfoElement.Placeholder="请输入文本"
                     Style="{StaticResource TextBoxExtend}"  />
        </StackPanel>

        <Button Width="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
csharp 复制代码
    /// <summary>
    /// TextDialogView.xaml 的交互逻辑
    /// </summary>
    public partial class TextDialogView
    {
        public TextDialogView()
        {
            InitializeComponent();
            //将本身指针传给ViewModel
            (this.DataContext as TextDialogViewModel).TextDialogView = this;
        }
    }
TextDialogViewModel
csharp 复制代码
 public partial class TextDialogViewModel : ObservableObject, IDialogResultable<string>
 {

     [ObservableProperty]
     private string testContent = "";

     public bool IsClick { get; set; }

     private TextDialogView textDialogView;

     /// <summary>
     /// 拿到TextDialogView的时候,添加点击函数
     /// </summary>
     public TextDialogView TextDialogView
     {
         get => textDialogView;
         set
         {
             textDialogView = value;
             textDialogView.MouseLeftButtonDown += (sender, e) =>
             {
                 IsClick = true;
             };
             textDialogView.MouseLeftButtonUp += (sender, e) =>
             {
                 IsClick = false;
             };
             textDialogView.MouseLeave += (sender, e) =>
             {
                 IsClick = false;
             };
         }
     }

     public TextDialogViewModel()
     {

     }

     /// <summary>
     /// 这个是回调的结果
     /// </summary>
     public string Result
     {
         get => TestContent; set
         {
             TestContent = value;
         }
     }
     /// <summary>
     /// 这个暂时我不知道有啥用
     /// </summary>
     public Action CloseAction { get; set; }


 }

运行结果

方法设计

Uniapp 将界面交互分为

  • 消息提示
  • 加载
  • 输入框
  • 列表选择

这个其实已经包含了大部分的交互内容了,如果想自定义,可以自己去研究一下。由于HandyControl已经封装了消息控件了,拿我们就封装另外三个功能了。


代码封装

由于代码比较复杂,我这里就放我的设计思路了。

我把详细的代码放在Gtiee仓库里面了

gclove2000 / WPF HandyControl 交互

静态方法

我把交互改成了静态的方法。


运行结果

相关推荐
samble10 小时前
从零搭建灌装监控系统(十):生产追溯,条码触发自动记录
c#·wpf·mvvm·modbus·工业控制
兰亭妙微UI设计公司11 小时前
兰亭妙微UI设计公司 蚂蚁阿福APP拆解:对话式交互如何重构就医全流程?
重构·交互
新新学长搞科研3 天前
【往届稳定EI+scopus检索】第三届人工智能、数字媒体技术与交互设计国际学术会议(ICADI 2026)
人工智能·交互·媒体
SamChan903 天前
PDF页面旋转与CropBox陷阱:译文回填位置总是错位的根因实测
python·ai·pdf·wpf
平头哥~3 天前
从文化 IP 解读到伴手礼定制,文创设计师智能体背后是 端到端具身交互智能落地
网络协议·tcp/ip·交互
大侠归来3 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
元岳数字人小元3 天前
数字人源码系统:模块化开发赋能智能场景灵活迭代升级
运维·人工智能·开源·人机交互·交互
李游Leo4 天前
《HarmonyOS 7 ArkGraphics 3D 空间设计开发实战》05:Camera控制、手势映射与空间浏览交互【鸿蒙心迹】
3d·交互·harmonyos
沫璃染墨4 天前
《Qt从零入门系列(十一):Qt事件机制详解——从QEvent到鼠标、键盘与定时器事件》
c++·qt·ui·硬件工程·交互·个人开发·qt5
SamChan904 天前
PDF翻译时页眉页脚总在捣乱?跨页重复文本块的检测与过滤实测
人工智能·python·ai·pdf·wpf