feat: add async command support.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Avalonia.Controls.Notifications;
|
using Avalonia.Controls.Notifications;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
@@ -15,12 +16,13 @@ public partial class PopConfirmDemoViewModel: ObservableObject
|
|||||||
|
|
||||||
public PopConfirmDemoViewModel()
|
public PopConfirmDemoViewModel()
|
||||||
{
|
{
|
||||||
ConfirmCommand = new RelayCommand(OnConfirm);
|
ConfirmCommand = new AsyncRelayCommand(OnConfirm);
|
||||||
CancelCommand = new RelayCommand(OnCancel);
|
CancelCommand = new RelayCommand(OnCancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnConfirm()
|
private async Task OnConfirm()
|
||||||
{
|
{
|
||||||
|
await Task.Delay(3000);
|
||||||
ToastManager?.Show(new Toast("Confirmed"), type: NotificationType.Success, classes: ["Light"]);
|
ToastManager?.Show(new Toast("Confirmed"), type: NotificationType.Success, classes: ["Light"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,24 @@
|
|||||||
<ControlTemplate TargetType="u:PopConfirm">
|
<ControlTemplate TargetType="u:PopConfirm">
|
||||||
<Panel>
|
<Panel>
|
||||||
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
|
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
|
||||||
<Popup IsOpen="True">
|
<Popup IsOpen="True"
|
||||||
|
Name="{x:Static u:PopConfirm.PART_Popup}"
|
||||||
|
Placement="Bottom" >
|
||||||
<Border Theme="{DynamicResource CardBorder}">
|
<Border Theme="{DynamicResource CardBorder}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<ContentPresenter Content="{TemplateBinding PopupHeader}" ContentTemplate="{TemplateBinding PopupHeaderTemplate}"/>
|
<ContentPresenter Content="{TemplateBinding PopupHeader}" ContentTemplate="{TemplateBinding PopupHeaderTemplate}"/>
|
||||||
<ContentPresenter Content="{TemplateBinding PopupContent}" ContentTemplate="{TemplateBinding PopupContentTemplate}"/>
|
<ContentPresenter Content="{TemplateBinding PopupContent}" ContentTemplate="{TemplateBinding PopupContentTemplate}"/>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="Confirm" Command="{TemplateBinding ConfirmCommand}" CommandParameter="{TemplateBinding ConfirmCommandParameter}"/>
|
<Button
|
||||||
<Button Content="Cancel" Command="{TemplateBinding CancelCommand}" CommandParameter="{TemplateBinding CancelCommandParameter}"/>
|
Name="{x:Static u:PopConfirm.PART_ConfirmButton}"
|
||||||
|
Content="Confirm"
|
||||||
|
Command="{TemplateBinding ConfirmCommand}"
|
||||||
|
CommandParameter="{TemplateBinding ConfirmCommandParameter}"/>
|
||||||
|
<Button
|
||||||
|
Name="{x:Static u:PopConfirm.PART_CancelButton}"
|
||||||
|
Content="Cancel"
|
||||||
|
Command="{TemplateBinding CancelCommand}"
|
||||||
|
CommandParameter="{TemplateBinding CancelCommandParameter}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Presenters;
|
using Avalonia.Controls.Presenters;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
using Irihi.Avalonia.Shared.Helpers;
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
|
|
||||||
@@ -11,6 +13,14 @@ namespace Ursa.Controls;
|
|||||||
|
|
||||||
public class PopConfirm: ContentControl
|
public class PopConfirm: ContentControl
|
||||||
{
|
{
|
||||||
|
public const string PART_ConfirmButton = "PART_ConfirmButton";
|
||||||
|
public const string PART_CancelButton = "PART_CancelButton";
|
||||||
|
public const string PART_Popup = "PART_Popup";
|
||||||
|
|
||||||
|
private Button? _confirmButton;
|
||||||
|
private Button? _cancelButton;
|
||||||
|
private Popup? _popup;
|
||||||
|
|
||||||
public static readonly StyledProperty<object?> PopupHeaderProperty = AvaloniaProperty.Register<PopConfirm, object?>(
|
public static readonly StyledProperty<object?> PopupHeaderProperty = AvaloniaProperty.Register<PopConfirm, object?>(
|
||||||
nameof(PopupHeader));
|
nameof(PopupHeader));
|
||||||
|
|
||||||
@@ -100,14 +110,7 @@ public class PopConfirm: ContentControl
|
|||||||
|
|
||||||
private void OnCommandChanged(AvaloniaPropertyChangedEventArgs<ICommand?> args)
|
private void OnCommandChanged(AvaloniaPropertyChangedEventArgs<ICommand?> args)
|
||||||
{
|
{
|
||||||
var newValue = args.GetNewValue<ICommand>();
|
|
||||||
newValue.CanExecuteChanged += (sender, e) =>
|
|
||||||
{
|
|
||||||
if (args.Sender is PopConfirm popconfirm)
|
|
||||||
{
|
|
||||||
var b = newValue.CanExecute(this.ConfirmCommandParameter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PopConfirm()
|
public PopConfirm()
|
||||||
@@ -129,8 +132,37 @@ public class PopConfirm: ContentControl
|
|||||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnApplyTemplate(e);
|
base.OnApplyTemplate(e);
|
||||||
|
_confirmButton = e.NameScope.Find<Button>(PART_ConfirmButton);
|
||||||
|
_cancelButton = e.NameScope.Find<Button>(PART_CancelButton);
|
||||||
|
_popup = e.NameScope.Find<Popup>(PART_Popup);
|
||||||
|
Button.ClickEvent.AddHandler(OnButtonClicked, _confirmButton, _cancelButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnButtonClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// This is a hack for MVVM toolkit that uses INotifyPropertyChanged for async command. It counts the number of
|
||||||
|
// IsRunning property changes to determine when the command is finished.
|
||||||
|
if (sender is Button button && button.Command is INotifyPropertyChanged inpc)
|
||||||
|
{
|
||||||
|
var count = 0;
|
||||||
|
void OnCommandPropertyChanged(object? sender, PropertyChangedEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.PropertyName != "IsRunning") return;
|
||||||
|
count++;
|
||||||
|
if (count != 2) return;
|
||||||
|
inpc.PropertyChanged -= OnCommandPropertyChanged;
|
||||||
|
_popup?.SetValue(Popup.IsOpenProperty, false);
|
||||||
|
}
|
||||||
|
inpc.PropertyChanged += OnCommandPropertyChanged;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_popup?.SetValue(Popup.IsOpenProperty, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private IDisposable? _childChangeDisposable;
|
private IDisposable? _childChangeDisposable;
|
||||||
|
|
||||||
protected override bool RegisterContentPresenter(ContentPresenter presenter)
|
protected override bool RegisterContentPresenter(ContentPresenter presenter)
|
||||||
|
|||||||
Reference in New Issue
Block a user