Skip to content

Commit 1088158

Browse files
committed
Merge branch 'main' into winui
2 parents 048fe04 + d1f334a commit 1088158

File tree

10 files changed

+214
-41
lines changed

10 files changed

+214
-41
lines changed

CommunityToolkit.Mvvm/Messaging/Messages/AsyncCollectionRequestMessage{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public async Task<IReadOnlyCollection<T>> GetResponsesAsync(CancellationToken ca
104104

105105
List<T> results = new(this.responses.Count);
106106

107-
await foreach (var response in this.WithCancellation(cancellationToken))
107+
await foreach (var response in this.WithCancellation(cancellationToken).ConfigureAwait(false))
108108
{
109109
results.Add(response);
110110
}

CommunityToolkit.WinUI.UI.Controls.Core/ImageEx/ImageExBase.Source.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ private void AttachSource(ImageSource source)
8888
{
8989
VisualStateManager.GoToState(this, UnloadedState, true);
9090
}
91+
else if (source is BitmapSource { PixelHeight: > 0, PixelWidth: > 0 })
92+
{
93+
VisualStateManager.GoToState(this, LoadedState, true);
94+
ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
95+
}
9196
}
9297

9398
private async void SetSource(object source)
@@ -124,8 +129,8 @@ private async void SetSource(object source)
124129
var url = source as string ?? source.ToString();
125130
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
126131
{
127-
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new UriFormatException("Invalid uri specified.")));
128132
VisualStateManager.GoToState(this, FailedState, true);
133+
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new UriFormatException("Invalid uri specified.")));
129134
return;
130135
}
131136
}
@@ -145,8 +150,8 @@ private async void SetSource(object source)
145150
}
146151
catch (Exception e)
147152
{
148-
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e));
149153
VisualStateManager.GoToState(this, FailedState, true);
154+
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e));
150155
}
151156
}
152157

@@ -232,4 +237,4 @@ protected virtual Task<ImageSource> ProvideCachedResourceAsync(Uri imageUri, Can
232237
return Task.FromResult((ImageSource)new BitmapImage(imageUri));
233238
}
234239
}
235-
}
240+
}

CommunityToolkit.WinUI.UI.Controls.Core/ImageEx/ImageExBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ protected override void OnApplyTemplate()
166166
/// <param name="e">Event Arguments</param>
167167
protected virtual void OnImageOpened(object sender, RoutedEventArgs e)
168168
{
169-
ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
170169
VisualStateManager.GoToState(this, LoadedState, true);
170+
ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
171171
}
172172

173173
/// <summary>
@@ -177,8 +177,8 @@ protected virtual void OnImageOpened(object sender, RoutedEventArgs e)
177177
/// <param name="e">Event Arguments</param>
178178
protected virtual void OnImageFailed(object sender, ExceptionRoutedEventArgs e)
179179
{
180-
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new Exception(e.ErrorMessage)));
181180
VisualStateManager.GoToState(this, FailedState, true);
181+
ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new Exception(e.ErrorMessage)));
182182
}
183183

184184
private void ImageExBase_LayoutUpdated(object sender, object e)

CommunityToolkit.WinUI.UI.Controls.Core/Menu/Menu.Events.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ private void Content_KeyDown(object sender, KeyRoutedEventArgs e)
105105
return;
106106
}
107107

108-
string gestureKey = MapInputToGestureKey(XamlRoot, e.Key);
108+
string gestureKey = MapInputToGestureKey(e.Key);
109109

110110
if (gestureKey == null)
111111
{
@@ -219,7 +219,7 @@ private void Content_ProcessKeyboardAccelerators(UIElement sender, ProcessKeyboa
219219

220220
if (args.Modifiers == VirtualKeyModifiers.Menu || !_isLostFocus)
221221
{
222-
var gestureKey = MapInputToGestureKey(XamlRoot, args.Key, !_isLostFocus);
222+
var gestureKey = MapInputToGestureKey(args.Key, !_isLostFocus);
223223
if (gestureKey == null)
224224
{
225225
return;

CommunityToolkit.WinUI.UI.Controls.Core/Menu/Menu.Logic.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44

55
using System.Linq;
66
using System.Text;
7-
using Microsoft.UI.Composition;
8-
using Microsoft.UI.Composition.Experimental;
9-
using Microsoft.UI.Input.Experimental;
7+
using Microsoft.UI.Input;
108
using Microsoft.UI.Xaml;
119
using Microsoft.UI.Xaml.Controls;
1210
using Microsoft.UI.Xaml.Controls.Primitives;
13-
using Microsoft.UI.Xaml.Hosting;
1411
using Microsoft.UI.Xaml.Input;
1512
using Windows.Foundation;
1613
using Windows.System;
@@ -138,13 +135,11 @@ private static MenuItem GetNextMenuItem(Menu menu, int moveCount)
138135
return nextItem;
139136
}
140137

141-
private static string MapInputToGestureKey(XamlRoot xamlRoot, VirtualKey key, bool menuHasFocus = false)
138+
private static string MapInputToGestureKey(VirtualKey key, bool menuHasFocus = false)
142139
{
143-
Compositor compositor = ElementCompositionPreview.GetElementVisual(xamlRoot.Content).Compositor;
144-
var keyboardInput = ExpKeyboardInput.GetForInputSite(ExpInputSite.GetOrCreateForContent(ExpCompositionContent.Create(compositor)));
145-
var isCtrlDown = keyboardInput.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
146-
var isShiftDown = keyboardInput.GetKeyState(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
147-
var isAltDown = keyboardInput.GetKeyState(VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down) || menuHasFocus;
140+
var isCtrlDown = KeyboardInput.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
141+
var isShiftDown = KeyboardInput.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
142+
var isAltDown = KeyboardInput.GetKeyStateForCurrentThread(VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down) || menuHasFocus;
148143

149144
if (!isCtrlDown && !isShiftDown && !isAltDown)
150145
{

CommunityToolkit.WinUI.UI.Controls.Core/TextToolbar/TextToolbar.Events.cs

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -250,43 +250,57 @@ private void Editor_KeyDown(object sender, KeyRoutedEventArgs e)
250250

251251
LastKeyPress = e.Key;
252252

253-
if (GetTemplateChild(RootControl) is CommandBar root)
253+
if (GetTemplateChild(RootControl) is CommandBar root && IsDoingShortcut(e.Key))
254254
{
255-
if (ControlKeyDown && e.Key != VirtualKey.Control)
256-
{
257-
var key = FindBestAlternativeKey(e.Key);
255+
var key = FindBestAlternativeKey(e.Key);
258256

259-
var matchingButtons = root.PrimaryCommands.OfType<ToolbarButton>().Where(item => item.ShortcutKey == key);
260-
if (matchingButtons.Any())
257+
var matchingButtons = root.PrimaryCommands.OfType<ToolbarButton>().Where(item => item.ShortcutKey == key);
258+
if (matchingButtons.Any())
259+
{
260+
if (e.Handled)
261261
{
262-
if (e.Handled)
262+
Editor.Document.Undo();
263+
if (string.IsNullOrWhiteSpace(Editor.Document.Selection.Text))
263264
{
264-
Editor.Document.Undo();
265-
if (string.IsNullOrWhiteSpace(Editor.Document.Selection.Text))
266-
{
267-
Editor.Document.Redo();
268-
}
265+
Editor.Document.Redo();
269266
}
267+
}
270268

271-
var args = new ShortcutKeyRequestArgs(key, ShiftKeyDown, e);
272-
foreach (var button in matchingButtons)
269+
var args = new ShortcutKeyRequestArgs(key, ShiftKeyDown, e);
270+
foreach (var button in matchingButtons)
271+
{
272+
if (button != null && !args.Handled)
273273
{
274-
if (button != null && !args.Handled)
275-
{
276-
button.ShortcutRequested(ref args);
277-
}
274+
button.ShortcutRequested(ref args);
278275
}
276+
}
279277

280-
ShortcutRequested?.Invoke(this, args);
281-
if (args.Handled)
282-
{
283-
e.Handled = true;
284-
}
278+
ShortcutRequested?.Invoke(this, args);
279+
if (args.Handled)
280+
{
281+
e.Handled = true;
285282
}
286283
}
287284
}
288285
}
289286

287+
private bool IsDoingShortcut(VirtualKey pressedKey)
288+
{
289+
// Control should be down
290+
if (!ControlKeyDown || pressedKey == VirtualKey.Control)
291+
{
292+
return false;
293+
}
294+
295+
// ignore when Control is used in combination with Menu (aka Alt) to avoid blocking use of AltGr key
296+
if (MenuKeyDown)
297+
{
298+
return false;
299+
}
300+
301+
return true;
302+
}
303+
290304
private KeyEventHandler KeyEventHandler { get; set; }
291305

292306
/// <summary>
@@ -297,6 +311,14 @@ public bool ControlKeyDown
297311
get { return IsKeyActive(KeyboardInput.GetKeyStateForCurrentThread(VirtualKey.Control)); }
298312
}
299313

314+
/// <summary>
315+
/// Gets a value indicating whether Menu is pressed down
316+
/// </summary>
317+
public bool MenuKeyDown
318+
{
319+
get { return IsKeyActive(KeyboardInput.GetKeyStateForCurrentThread(VirtualKey.Menu)); }
320+
}
321+
300322
/// <summary>
301323
/// Gets a value indicating whether Shift is pressed down
302324
/// </summary>

UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.Request.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.Collections.Generic;
7+
using System.Linq;
78
using System.Threading.Tasks;
89
using CommunityToolkit.Mvvm.Messaging;
910
using CommunityToolkit.Mvvm.Messaging.Messages;
@@ -73,6 +74,8 @@ void Receive(object recipient, NumberRequestMessage m)
7374
messenger.Register<NumberRequestMessage>(recipient, Receive);
7475

7576
int result = messenger.Send<NumberRequestMessage>();
77+
78+
GC.KeepAlive(recipient);
7679
}
7780

7881
public class NumberRequestMessage : RequestMessage<int>
@@ -102,6 +105,8 @@ void Receive(object recipient, AsyncNumberRequestMessage m)
102105
int result = await messenger.Send<AsyncNumberRequestMessage>();
103106

104107
Assert.AreEqual(result, 42);
108+
109+
GC.KeepAlive(recipient);
105110
}
106111

107112
[TestCategory("Mvvm")]
@@ -134,6 +139,8 @@ void Receive(object recipient, AsyncNumberRequestMessage m)
134139
int result = await messenger.Send<AsyncNumberRequestMessage>();
135140

136141
Assert.AreEqual(result, 42);
142+
143+
GC.KeepAlive(recipient);
137144
}
138145

139146
[TestCategory("Mvvm")]
@@ -167,6 +174,8 @@ void Receive(object recipient, AsyncNumberRequestMessage m)
167174
messenger.Register<AsyncNumberRequestMessage>(recipient, Receive);
168175

169176
int result = await messenger.Send<AsyncNumberRequestMessage>();
177+
178+
GC.KeepAlive(recipient);
170179
}
171180

172181
public class AsyncNumberRequestMessage : AsyncRequestMessage<int>
@@ -191,6 +200,8 @@ void Receive(object recipient, NumbersCollectionRequestMessage m)
191200
var results = messenger.Send<NumbersCollectionRequestMessage>().Responses;
192201

193202
Assert.AreEqual(results.Count, 0);
203+
204+
GC.KeepAlive(recipient);
194205
}
195206

196207
[TestCategory("Mvvm")]
@@ -266,6 +277,8 @@ void Receive(object recipient, AsyncNumbersCollectionRequestMessage m)
266277
var results = await messenger.Send<AsyncNumbersCollectionRequestMessage>().GetResponsesAsync();
267278

268279
Assert.AreEqual(results.Count, 0);
280+
281+
GC.KeepAlive(recipient);
269282
}
270283

271284
[TestCategory("Mvvm")]
@@ -298,6 +311,46 @@ async Task<int> GetNumberAsync()
298311
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient3, Receive3);
299312
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient4, Receive4);
300313

314+
var responses = await messenger.Send<AsyncNumbersCollectionRequestMessage>().GetResponsesAsync();
315+
316+
CollectionAssert.AreEquivalent(responses.ToArray(), new[] { 1, 2, 3, 3 });
317+
318+
GC.KeepAlive(recipient1);
319+
GC.KeepAlive(recipient2);
320+
GC.KeepAlive(recipient3);
321+
GC.KeepAlive(recipient4);
322+
}
323+
324+
[TestCategory("Mvvm")]
325+
[TestMethod]
326+
[DataRow(typeof(StrongReferenceMessenger))]
327+
[DataRow(typeof(WeakReferenceMessenger))]
328+
public async Task Test_Messenger_AsyncCollectionRequestMessage_Ok_MultipleReplies_Enumerate(Type type)
329+
{
330+
var messenger = (IMessenger)Activator.CreateInstance(type);
331+
object
332+
recipient1 = new object(),
333+
recipient2 = new object(),
334+
recipient3 = new object(),
335+
recipient4 = new object();
336+
337+
async Task<int> GetNumberAsync()
338+
{
339+
await Task.Delay(100);
340+
341+
return 3;
342+
}
343+
344+
void Receive1(object recipient, AsyncNumbersCollectionRequestMessage m) => m.Reply(1);
345+
void Receive2(object recipient, AsyncNumbersCollectionRequestMessage m) => m.Reply(Task.FromResult(2));
346+
void Receive3(object recipient, AsyncNumbersCollectionRequestMessage m) => m.Reply(GetNumberAsync());
347+
void Receive4(object recipient, AsyncNumbersCollectionRequestMessage m) => m.Reply(_ => GetNumberAsync());
348+
349+
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient1, Receive1);
350+
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient2, Receive2);
351+
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient3, Receive3);
352+
messenger.Register<AsyncNumbersCollectionRequestMessage>(recipient4, Receive4);
353+
301354
List<int> responses = new List<int>();
302355

303356
await foreach (var response in messenger.Send<AsyncNumbersCollectionRequestMessage>())
@@ -306,6 +359,11 @@ async Task<int> GetNumberAsync()
306359
}
307360

308361
CollectionAssert.AreEquivalent(responses, new[] { 1, 2, 3, 3 });
362+
363+
GC.KeepAlive(recipient1);
364+
GC.KeepAlive(recipient2);
365+
GC.KeepAlive(recipient3);
366+
GC.KeepAlive(recipient4);
309367
}
310368

311369
public class AsyncNumbersCollectionRequestMessage : AsyncCollectionRequestMessage<int>
Loading

0 commit comments

Comments
 (0)