我学了HandyControl的基础使用,但是发现HandyControl 封装了基础的消息提示,但是没有封装基础的交互逻辑。可能是因为我写了Uniapp,我知道封装了基础的交互其实一般就够用了。
Uniapp 界面交互反馈
我现在觉得,代码要低耦合一点,每个模块都纯粹一点,这一次我就不添加Nlog日志打印了。
因为最后代码比较多,我就放在仓库里了
gclove2000 / WPF HandyControl 交互
HandyControl Github地址
HandyControl 官方中文文档
WPF-UI HandyControl 简单介绍
WPF-UI HandyControl 控件简单实战+IconPacks矢量图导入
WPF 消息日志打印帮助类:HandyControl+NLog+彩色控制台打印+全局异常捕捉
HandyControl Dialog 对话框
顺便再装一个CommunityToolkit.MVVM
<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>
namespace HandyControlDemo.UserControl
{
public partial class TextDialog
{
public TextDialog()
{
InitializeComponent();
}
}
}
我现在才知道,原来想要弹窗的边框为圆角,要将UserControl改为Border
按钮加个显示就可以了
Dialog.Show(new TextDialogView());
虽然HandyControl实现了这个功能,但是文档写的很少
<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>
public partial class TextDialogViewModel : ObservableObject, IDialogResultable<string>
{
[ObservableProperty]
private string testContent = "";
public TextDialogViewModel()
{
}
///
/// 这个是回调的结果
///
public string Result
{
get => TestContent; set
{
TestContent = value;
}
}
///
/// 这个暂时我不知道有啥用
///
public Action CloseAction { get; set; }
}
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给了我们两个取消弹窗的方式
如果出现了以下问题,要注意窗口线程是不能开启新的线程的
C#调用线程必须为 STA,因为许多 UI 组件都需要。
我找了一天了,还是没找到方法
【WPF】查找父/子控件(元素、节点)
How could I close a Interactive Dialog when clicking outside #1272
哎,看起来还是得用点奇技淫巧
额,可能说的比较复杂。简单来说就是背景点击的时候,对话框没点击,那就是外侧点击了。
<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 的交互逻辑
///
public partial class TextDialogView
{
public TextDialogView()
{
InitializeComponent();
//将本身指针传给ViewModel
(this.DataContext as TextDialogViewModel).TextDialogView = this;
}
}
public partial class TextDialogViewModel : ObservableObject, IDialogResultable<string>
{
[ObservableProperty]
private string testContent = "";
public bool IsClick { get; set; }
private TextDialogView textDialogView;
///
/// 拿到TextDialogView的时候,添加点击函数
///
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()
{
}
///
/// 这个是回调的结果
///
public string Result
{
get => TestContent; set
{
TestContent = value;
}
}
///
/// 这个暂时我不知道有啥用
///
public Action CloseAction { get; set; }
}
Uniapp 将界面交互分为
这个其实已经包含了大部分的交互内容了,如果想自定义,可以自己去研究一下。由于HandyControl已经封装了消息控件了,拿我们就封装另外三个功能了。
由于代码比较复杂,我这里就放我的设计思路了。
我把详细的代码放在Gtiee仓库里面了
gclove2000 / WPF HandyControl 交互