Skip to content

Commit 48e7966

Browse files
committed
change to avalonia
1 parent e09a314 commit 48e7966

23 files changed

Lines changed: 682 additions & 620 deletions

src/App.axaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Application xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:vm="using:ModernContextMenuManager.ViewModels"
4+
xmlns:helper="using:ModernContextMenuManager.Helpers"
5+
x:Class="ModernContextMenuManager.App"
6+
RequestedThemeVariant="Default">
7+
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
8+
9+
<Application.Styles>
10+
<FluentTheme />
11+
</Application.Styles>
12+
13+
<Application.Resources>
14+
<vm:ViewModelLocator x:Key="Locator" />
15+
<helper:NotConverter x:Key="NotConverter" />
16+
<helper:StringIsEmptyConverter x:Key="StringIsEmptyConverter" />
17+
<helper:StringIsNotEmptyConverter x:Key="StringIsNotEmptyConverter" />
18+
</Application.Resources>
19+
</Application>

src/App.axaml.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Avalonia;
2+
using Avalonia.Controls.ApplicationLifetimes;
3+
using Avalonia.Markup.Xaml;
4+
5+
namespace ModernContextMenuManager;
6+
7+
public partial class App : Application
8+
{
9+
public override void Initialize()
10+
{
11+
AvaloniaXamlLoader.Load(this);
12+
}
13+
14+
public override void OnFrameworkInitializationCompleted()
15+
{
16+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
17+
{
18+
desktop.MainWindow = new MainWindow();
19+
}
20+
21+
base.OnFrameworkInitializationCompleted();
22+
}
23+
}

src/Base/ObservableObject.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using Avalonia.Threading;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.ComponentModel;
5+
using System.Linq;
6+
using System.Runtime.CompilerServices;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace ModernContextMenuManager.Base
11+
{
12+
public partial class ObservableObject : INotifyPropertyChanged
13+
{
14+
protected virtual bool SetProperty<T>(ref T field, T value, OnPropertyChangingDelegate<T>? onPropertyChanging = null, OnPropertyChangedDelegate<T>? onPropertyChanged = null, [CallerMemberName] string? propertyName = null, bool notifyWhenNotChanged = false, bool asyncNotifyWhenNotChanged = false)
15+
{
16+
if (!EqualityComparer<T>.Default.Equals(field, value))
17+
{
18+
if (onPropertyChanging != null && !onPropertyChanging.Invoke(field, value))
19+
{
20+
if (notifyWhenNotChanged)
21+
{
22+
Notify(asyncNotifyWhenNotChanged, propertyName);
23+
}
24+
return false;
25+
}
26+
var oldValue = field;
27+
field = value;
28+
Notify(false, propertyName);
29+
onPropertyChanged?.Invoke(oldValue, value);
30+
return true;
31+
}
32+
return false;
33+
34+
async void Notify(bool _async, string? _propertyName)
35+
{
36+
var handler = PropertyChanged;
37+
if (handler != null)
38+
{
39+
if (_async)
40+
{
41+
Dispatcher.UIThread.VerifyAccess();
42+
await Dispatcher.UIThread.InvokeAsync(() => { }, DispatcherPriority.Loaded);
43+
}
44+
else
45+
{
46+
OnPropertyChanged(_propertyName);
47+
}
48+
}
49+
}
50+
}
51+
52+
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
53+
{
54+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
55+
}
56+
57+
protected delegate bool OnPropertyChangingDelegate<T>(T oldValue, T newValue);
58+
protected delegate void OnPropertyChangedDelegate<T>(T oldValue, T newValue);
59+
60+
public event PropertyChangedEventHandler? PropertyChanged;
61+
}
62+
}

src/Base/RelayCommand.cs

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows.Input;
8+
9+
namespace ModernContextMenuManager.Base
10+
{
11+
public partial class RelayCommand : ICommand
12+
{
13+
private readonly Action action;
14+
private readonly Func<bool>? canExecute;
15+
16+
public event EventHandler? CanExecuteChanged;
17+
18+
public RelayCommand(Action action) : this(action, null) { }
19+
20+
public RelayCommand(Action action, Func<bool>? canExecute)
21+
{
22+
this.action = action;
23+
this.canExecute = canExecute;
24+
}
25+
26+
public bool CanExecute(object? parameter)
27+
{
28+
if (canExecute == null) return true;
29+
return canExecute.Invoke();
30+
}
31+
32+
public void Execute(object? parameter)
33+
{
34+
this.Execute();
35+
}
36+
37+
public void Execute()
38+
{
39+
action.Invoke();
40+
}
41+
42+
public void RaiseCanExecuteChanged()
43+
{
44+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
45+
}
46+
}
47+
48+
public partial class RelayCommand<T> : ICommand
49+
{
50+
private readonly Action<T?> action;
51+
private readonly Func<T?, bool>? canExecute;
52+
53+
public event EventHandler? CanExecuteChanged;
54+
55+
public RelayCommand(Action<T?> action) : this(action, null) { }
56+
57+
public RelayCommand(Action<T?> action, Func<T?, bool>? canExecute)
58+
{
59+
this.action = action;
60+
this.canExecute = canExecute;
61+
}
62+
63+
public bool CanExecute(object? parameter)
64+
{
65+
if (canExecute == null) return true;
66+
return canExecute.Invoke((T?)parameter);
67+
}
68+
69+
public void Execute(object? parameter)
70+
{
71+
action.Invoke((T?)parameter);
72+
}
73+
74+
public void RaiseCanExecuteChanged()
75+
{
76+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
77+
}
78+
}
79+
80+
public partial class AsyncRelayCommand : ICommand, INotifyPropertyChanged
81+
{
82+
private readonly Func<Task> action;
83+
private readonly Func<bool>? canExecute;
84+
85+
private Task? task;
86+
87+
public event EventHandler? CanExecuteChanged;
88+
public event PropertyChangedEventHandler? PropertyChanged;
89+
90+
public AsyncRelayCommand(Func<Task> action) : this(action, null) { }
91+
92+
public AsyncRelayCommand(Func<Task> action, Func<bool>? canExecute)
93+
{
94+
this.action = action;
95+
this.canExecute = canExecute;
96+
}
97+
98+
public bool IsRunning
99+
{
100+
get
101+
{
102+
var _task = task;
103+
return _task != null && !_task.IsCompleted;
104+
}
105+
}
106+
107+
public bool CanExecute(object? parameter)
108+
{
109+
if (canExecute == null) return true;
110+
var _task = task;
111+
if (_task != null && !_task.IsCompleted) return false;
112+
113+
return canExecute.Invoke();
114+
}
115+
116+
public void Execute(object? parameter)
117+
{
118+
_ = ExecuteAsync();
119+
}
120+
121+
public Task ExecuteAsync()
122+
{
123+
var _task = task;
124+
if (_task != null && !_task.IsCompleted) return _task;
125+
126+
return RunAsync();
127+
128+
async Task RunAsync()
129+
{
130+
var _task = task = action.Invoke();
131+
RaiseCanExecuteChanged();
132+
try
133+
{
134+
await _task;
135+
RaiseCanExecuteChanged();
136+
}
137+
finally
138+
{
139+
task = null;
140+
}
141+
}
142+
}
143+
144+
public void RaiseCanExecuteChanged()
145+
{
146+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
147+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRunning)));
148+
}
149+
}
150+
151+
public partial class AsyncRelayCommand<T> : ICommand, INotifyPropertyChanged
152+
{
153+
private readonly Func<T?, Task> action;
154+
private readonly Func<T?, bool>? canExecute;
155+
156+
private Task? task;
157+
158+
public event EventHandler? CanExecuteChanged;
159+
public event PropertyChangedEventHandler? PropertyChanged;
160+
161+
public AsyncRelayCommand(Func<T?, Task> action) : this(action, null) { }
162+
163+
public AsyncRelayCommand(Func<T?, Task> action, Func<T?, bool>? canExecute)
164+
{
165+
this.action = action;
166+
this.canExecute = canExecute;
167+
}
168+
169+
public bool IsRunning
170+
{
171+
get
172+
{
173+
var _task = task;
174+
return _task != null && !_task.IsCompleted;
175+
}
176+
}
177+
178+
public bool CanExecute(object? parameter)
179+
{
180+
if (canExecute == null) return true;
181+
var _task = task;
182+
if (_task != null && !_task.IsCompleted) return false;
183+
184+
return canExecute.Invoke((T?)parameter);
185+
}
186+
187+
public void Execute(object? parameter)
188+
{
189+
_ = ExecuteAsync((T?)parameter);
190+
}
191+
192+
public Task ExecuteAsync(T? parameter)
193+
{
194+
var _task = task;
195+
if (_task != null && !_task.IsCompleted) return _task;
196+
197+
return RunAsync();
198+
199+
async Task RunAsync()
200+
{
201+
var _task = task = action.Invoke(parameter);
202+
RaiseCanExecuteChanged();
203+
try
204+
{
205+
await _task;
206+
RaiseCanExecuteChanged();
207+
}
208+
finally
209+
{
210+
task = null;
211+
}
212+
}
213+
}
214+
215+
public void RaiseCanExecuteChanged()
216+
{
217+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
218+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRunning)));
219+
}
220+
}
221+
}

0 commit comments

Comments
 (0)