Skip to content

Commit dcd7014

Browse files
Merge branch 'main' into rangeselector-tests
2 parents 1de7dbd + d1f334a commit dcd7014

File tree

8 files changed

+207
-29
lines changed

8 files changed

+207
-29
lines changed

Microsoft.Toolkit.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
}

Microsoft.Toolkit.Uwp.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+
}

Microsoft.Toolkit.Uwp.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)

Microsoft.Toolkit.Uwp.UI.Controls.Core/TextToolbar/TextToolbar.Events.cs

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

249249
LastKeyPress = e.Key;
250250

251-
if (GetTemplateChild(RootControl) is CommandBar root)
251+
if (GetTemplateChild(RootControl) is CommandBar root && IsDoingShortcut(e.Key))
252252
{
253-
if (ControlKeyDown && e.Key != VirtualKey.Control)
254-
{
255-
var key = FindBestAlternativeKey(e.Key);
253+
var key = FindBestAlternativeKey(e.Key);
256254

257-
var matchingButtons = root.PrimaryCommands.OfType<ToolbarButton>().Where(item => item.ShortcutKey == key);
258-
if (matchingButtons.Any())
255+
var matchingButtons = root.PrimaryCommands.OfType<ToolbarButton>().Where(item => item.ShortcutKey == key);
256+
if (matchingButtons.Any())
257+
{
258+
if (e.Handled)
259259
{
260-
if (e.Handled)
260+
Editor.Document.Undo();
261+
if (string.IsNullOrWhiteSpace(Editor.Document.Selection.Text))
261262
{
262-
Editor.Document.Undo();
263-
if (string.IsNullOrWhiteSpace(Editor.Document.Selection.Text))
264-
{
265-
Editor.Document.Redo();
266-
}
263+
Editor.Document.Redo();
267264
}
265+
}
268266

269-
var args = new ShortcutKeyRequestArgs(key, ShiftKeyDown, e);
270-
foreach (var button in matchingButtons)
267+
var args = new ShortcutKeyRequestArgs(key, ShiftKeyDown, e);
268+
foreach (var button in matchingButtons)
269+
{
270+
if (button != null && !args.Handled)
271271
{
272-
if (button != null && !args.Handled)
273-
{
274-
button.ShortcutRequested(ref args);
275-
}
272+
button.ShortcutRequested(ref args);
276273
}
274+
}
277275

278-
ShortcutRequested?.Invoke(this, args);
279-
if (args.Handled)
280-
{
281-
e.Handled = true;
282-
}
276+
ShortcutRequested?.Invoke(this, args);
277+
if (args.Handled)
278+
{
279+
e.Handled = true;
283280
}
284281
}
285282
}
286283
}
287284

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

290304
/// <summary>
@@ -295,6 +309,14 @@ public bool ControlKeyDown
295309
get { return IsKeyActive(CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control)); }
296310
}
297311

312+
/// <summary>
313+
/// Gets a value indicating whether Menu is pressed down
314+
/// </summary>
315+
public bool MenuKeyDown
316+
{
317+
get { return IsKeyActive(CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Menu)); }
318+
}
319+
298320
/// <summary>
299321
/// Gets a value indicating whether Shift is pressed down
300322
/// </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 Microsoft.Toolkit.Mvvm.Messaging;
910
using Microsoft.Toolkit.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
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.Toolkit.Uwp;
6+
using Microsoft.Toolkit.Uwp.UI;
7+
using Microsoft.Toolkit.Uwp.UI.Controls;
8+
using Microsoft.VisualStudio.TestTools.UnitTesting;
9+
using System;
10+
using System.IO;
11+
using System.Linq;
12+
using System.Reflection;
13+
using System.Threading.Tasks;
14+
using Windows.UI.Xaml;
15+
using Windows.UI.Xaml.Controls;
16+
using Windows.UI.Xaml.Media.Imaging;
17+
18+
namespace UnitTests.UWP.UI.Controls
19+
{
20+
[TestClass]
21+
public class Test_ImageEx : VisualUITestBase
22+
{
23+
private const string ImageString = "data:image/png;base64,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";
24+
25+
[TestMethod]
26+
public async Task SetSourceToOpenedBitmapImage()
27+
{
28+
await App.DispatcherQueue.EnqueueAsync(async () =>
29+
{
30+
var bitmapImage = new BitmapImage();
31+
32+
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(@"UnitTests.UWP.Assets.StoreLogo.embeded.png");
33+
using var memStream = new MemoryStream();
34+
await stream.CopyToAsync(memStream);
35+
memStream.Seek(0, SeekOrigin.Begin);
36+
await bitmapImage.SetSourceAsync(memStream.AsRandomAccessStream());
37+
38+
var imageLoader = new ImageEx();
39+
40+
await SetTestContentAsync(imageLoader);
41+
42+
Assert.AreEqual("Unloaded", GetCurrentState(imageLoader));
43+
44+
var imageOpendedCallCount = 0;
45+
46+
imageLoader.ImageExOpened += (s, e) =>
47+
{
48+
imageOpendedCallCount++;
49+
Assert.AreEqual("Loaded", GetCurrentState(imageLoader));
50+
};
51+
52+
imageLoader.Source = bitmapImage;
53+
54+
Assert.AreEqual(1, imageOpendedCallCount, "{0} should only be called once", nameof(ImageEx.ImageExOpened));
55+
});
56+
}
57+
58+
[TestMethod]
59+
[DataRow(ImageString)]
60+
[DataRow(@"ms-appx:///Assets/StoreLogo.png")]
61+
public async Task SetSourceToUri(string uri)
62+
{
63+
await App.DispatcherQueue.EnqueueAsync(async () =>
64+
{
65+
var imageLoader = new ImageEx();
66+
67+
await SetTestContentAsync(imageLoader);
68+
69+
Assert.AreEqual("Unloaded", GetCurrentState(imageLoader));
70+
71+
var imageOpendedCallCount = 0;
72+
imageLoader.ImageExOpened += (s, e) =>
73+
{
74+
imageOpendedCallCount++;
75+
Assert.AreEqual("Loaded", GetCurrentState(imageLoader));
76+
};
77+
78+
imageLoader.Source = new Uri(uri);
79+
80+
// TODO (2021.05.11): Test in a more deterministic way.
81+
// Setting source causes some async code to trigger and
82+
// we have no way to await or handle its complementation regardless of the result.
83+
await Task.Delay(1000);
84+
Assert.AreEqual(1, imageOpendedCallCount, "{0} should only be called once", nameof(ImageEx.ImageExOpened));
85+
});
86+
}
87+
88+
private static string GetCurrentState(ImageEx image)
89+
=> VisualStateManager.GetVisualStateGroups(image.FindDescendant<Grid>()).First(g => g.Name == "CommonStates").CurrentState.Name;
90+
}
91+
}

UnitTests/UnitTests.UWP/UnitTests.UWP.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
<Compile Include="UI\Collection\Test_IncrementalLoadingCollection.cs" />
203203
<Compile Include="UI\Controls\Test_Carousel.cs" />
204204
<Compile Include="UI\Controls\Test_BladeView.cs" />
205+
<Compile Include="UI\Controls\Test_ImageEx.cs" />
205206
<Compile Include="UI\Controls\Test_RadialGauge.cs" />
206207
<Compile Include="UI\Controls\Test_TextToolbar_Localization.cs" />
207208
<Compile Include="UI\Controls\Test_InfiniteCanvas_Regression.cs" />
@@ -243,6 +244,7 @@
243244
</ItemGroup>
244245
<ItemGroup>
245246
<Content Include="Assets\Samples\lorem.txt" />
247+
<EmbeddedResource Include="Assets\StoreLogo.embeded.png" />
246248
<Content Include="Properties\UnitTestApp.rd.xml" />
247249
<Content Include="Assets\LockScreenLogo.scale-200.png" />
248250
<Content Include="Assets\SplashScreen.scale-200.png" />

0 commit comments

Comments
 (0)