Skip to content

Commit e093edf

Browse files
authored
[Windows] fixing window glitches while moving or resizing (#14861)
* Window glitch fix for windows * Minor refactoring
1 parent 800b5b0 commit e093edf

2 files changed

Lines changed: 63 additions & 17 deletions

File tree

src/Controls/src/Core/Window/Window.cs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,24 +210,58 @@ double GetSizeCoordinate(BindableProperty property)
210210

211211
void IWindow.FrameChanged(Rect frame)
212212
{
213-
if (new Rect(X, Y, Width, Height) == frame)
213+
var x = X;
214+
var y = Y;
215+
var width = Width;
216+
var height = Height;
217+
if (new Rect(x, y, width, height) == frame)
214218
return;
215219

216220
_batchFrameUpdate++;
217221

218-
X = frame.X;
219-
Y = frame.Y;
220-
Width = frame.Width;
221-
Height = frame.Height;
222+
SetPropertyChanging(XProperty, nameof(X), x, frame.X);
223+
SetPropertyChanging(YProperty, nameof(Y), y, frame.Y);
224+
SetPropertyChanging(WidthProperty, nameof(Width), width, frame.Width);
225+
SetPropertyChanging(HeightProperty, nameof(Height), height, frame.Height);
226+
227+
SetValueCore(XProperty, frame.X, SetValueFlags.None, SetValuePrivateFlags.Silent);
228+
SetValueCore(YProperty, frame.Y, SetValueFlags.None, SetValuePrivateFlags.Silent);
229+
SetValueCore(WidthProperty, frame.Width, SetValueFlags.None, SetValuePrivateFlags.Silent);
230+
SetValueCore(HeightProperty, frame.Height, SetValueFlags.None, SetValuePrivateFlags.Silent);
222231

223232
_batchFrameUpdate--;
224233
if (_batchFrameUpdate < 0)
225234
_batchFrameUpdate = 0;
226235

227236
if (_batchFrameUpdate == 0)
228237
{
238+
SetPropertyChanged(XProperty, nameof(X), x, frame.X);
239+
SetPropertyChanged(YProperty, nameof(Y), y, frame.Y);
240+
SetPropertyChanged(WidthProperty, nameof(Width), width, frame.Width);
241+
SetPropertyChanged(HeightProperty, nameof(Height), height, frame.Height);
242+
229243
SizeChanged?.Invoke(this, EventArgs.Empty);
230244
}
245+
246+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
247+
void SetPropertyChanging(BindableProperty property, string name, double oldValue, double newValue)
248+
{
249+
if (oldValue == newValue)
250+
return;
251+
252+
property.PropertyChanging?.Invoke(this, oldValue, newValue);
253+
OnPropertyChanging(name);
254+
}
255+
256+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
257+
void SetPropertyChanged(BindableProperty property, string name, double oldValue, double newValue)
258+
{
259+
if (oldValue == newValue)
260+
return;
261+
262+
OnPropertyChanged(name);
263+
property.PropertyChanged?.Invoke(this, oldValue, newValue);
264+
}
231265
}
232266

233267
public event EventHandler<ModalPoppedEventArgs>? ModalPopped;

src/Controls/tests/Core.UnitTests/WindowsTests.cs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -434,70 +434,82 @@ void ValidateSetup(Application app, Page page = null)
434434
public void SettingCoreFrameOnlyFiresEventOnce()
435435
{
436436
var sizeChangedCount = 0;
437-
var propertyChanges = new List<string>();
437+
var changingProperties = new List<string>();
438+
var changedProperties = new List<string>();
438439

439440
var window = new TestWindow();
440441
window.SizeChanged += (sender, e) => sizeChangedCount++;
441-
window.PropertyChanged += (sender, e) => propertyChanges.Add(e.PropertyName);
442+
window.PropertyChanging += (sender, e) => changingProperties.Add(e.PropertyName);
443+
window.PropertyChanged += (sender, e) => changedProperties.Add(e.PropertyName);
442444

443445
((IWindow)window).FrameChanged(new Rect(100, 200, 300, 400));
444446

445447
Assert.Equal(1, sizeChangedCount);
446-
Assert.Equal(new[] { "X", "Y", "Width", "Height" }, propertyChanges);
448+
Assert.Equal(new[] { "X", "Y", "Width", "Height" }, changingProperties);
449+
Assert.Equal(new[] { "X", "Y", "Width", "Height" }, changedProperties);
447450
}
448451

449452
[Fact]
450453
public void SettingSameCoreFrameDoesNothing()
451454
{
452455
var sizeChangedCount = 0;
453-
var propertyChanges = new List<string>();
456+
var changingProperties = new List<string>();
457+
var changedProperties = new List<string>();
454458

455459
var window = new TestWindow();
456460
((IWindow)window).FrameChanged(new Rect(100, 200, 300, 400));
457461

458462
window.SizeChanged += (sender, e) => sizeChangedCount++;
459-
window.PropertyChanged += (sender, e) => propertyChanges.Add(e.PropertyName);
463+
window.PropertyChanging += (sender, e) => changingProperties.Add(e.PropertyName);
464+
window.PropertyChanged += (sender, e) => changedProperties.Add(e.PropertyName);
460465

461466
((IWindow)window).FrameChanged(new Rect(100, 200, 300, 400));
462467

463468
Assert.Equal(0, sizeChangedCount);
464-
Assert.Empty(propertyChanges);
469+
Assert.Empty(changingProperties);
470+
Assert.Empty(changedProperties);
465471
}
466472

467473
[Fact]
468474
public void UpdatingSingleCoordinateOnlyFiresSinglePropertyAndFrameEvent()
469475
{
470476
var sizeChangedCount = 0;
471-
var propertyChanges = new List<string>();
477+
var changingProperties = new List<string>();
478+
var changedProperties = new List<string>();
472479

473480
var window = new TestWindow();
474481
((IWindow)window).FrameChanged(new Rect(100, 200, 300, 400));
475482

476483
window.SizeChanged += (sender, e) => sizeChangedCount++;
477-
window.PropertyChanged += (sender, e) => propertyChanges.Add(e.PropertyName);
484+
window.PropertyChanging += (sender, e) => changingProperties.Add(e.PropertyName);
485+
window.PropertyChanged += (sender, e) => changedProperties.Add(e.PropertyName);
478486

479487
((IWindow)window).FrameChanged(new Rect(100, 250, 300, 400));
480488

481489
Assert.Equal(1, sizeChangedCount);
482-
Assert.Equal(new[] { "Y" }, propertyChanges);
490+
Assert.Equal(new[] { "Y" }, changingProperties);
491+
Assert.Equal(new[] { "Y" }, changedProperties);
483492
}
484493

485494
[Fact]
486495
public void UpdatingSingleBoundOnlyFiresSingleProperty()
487496
{
488497
var sizeChangedCount = 0;
489-
var propertyChanges = new List<string>();
498+
var changingProperties = new List<string>();
499+
var changedProperties = new List<string>();
490500

491501
var window = new TestWindow();
492502
((IWindow)window).FrameChanged(new Rect(100, 200, 300, 400));
493503

494504
window.SizeChanged += (sender, e) => sizeChangedCount++;
495-
window.PropertyChanged += (sender, e) => propertyChanges.Add(e.PropertyName);
505+
window.PropertyChanging += (sender, e) => changingProperties.Add(e.PropertyName);
506+
window.PropertyChanged += (sender, e) => changedProperties.Add(e.PropertyName);
496507

497508
((IWindow)window).FrameChanged(new Rect(100, 200, 350, 400));
498509

499510
Assert.Equal(1, sizeChangedCount);
500-
Assert.Equal(new[] { "Width" }, propertyChanges);
511+
Assert.Equal(new[] { "Width" }, changingProperties);
512+
Assert.Equal(new[] { "Width" }, changedProperties);
501513
}
502514

503515
[Fact]

0 commit comments

Comments
 (0)