WindowTests.cs 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Avalonia.Platform;
  5. using Avalonia.Rendering;
  6. using Avalonia.UnitTests;
  7. using Moq;
  8. using Xunit;
  9. namespace Avalonia.Controls.UnitTests
  10. {
  11. public class WindowTests
  12. {
  13. [Fact]
  14. public void Setting_Title_Should_Set_Impl_Title()
  15. {
  16. var windowImpl = new Mock<IWindowImpl>();
  17. var windowingPlatform = new MockWindowingPlatform(() => windowImpl.Object);
  18. using (UnitTestApplication.Start(new TestServices(windowingPlatform: windowingPlatform)))
  19. {
  20. var target = new Window();
  21. target.Title = "Hello World";
  22. windowImpl.Verify(x => x.SetTitle("Hello World"));
  23. }
  24. }
  25. [Fact]
  26. public void IsVisible_Should_Initially_Be_False()
  27. {
  28. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  29. {
  30. var window = new Window();
  31. Assert.False(window.IsVisible);
  32. }
  33. }
  34. [Fact]
  35. public void IsVisible_Should_Be_True_After_Show()
  36. {
  37. using (UnitTestApplication.Start(TestServices.StyledWindow))
  38. {
  39. var window = new Window();
  40. window.Show();
  41. Assert.True(window.IsVisible);
  42. }
  43. }
  44. [Fact]
  45. public void IsVisible_Should_Be_True_After_ShowDialog()
  46. {
  47. using (UnitTestApplication.Start(TestServices.StyledWindow))
  48. {
  49. var parent = new Window();
  50. parent.Show();
  51. var window = new Window();
  52. var task = window.ShowDialog(parent);
  53. Assert.True(window.IsVisible);
  54. }
  55. }
  56. [Fact]
  57. public void IsVisible_Should_Be_False_After_Hide()
  58. {
  59. using (UnitTestApplication.Start(TestServices.StyledWindow))
  60. {
  61. var window = new Window();
  62. window.Show();
  63. window.Hide();
  64. Assert.False(window.IsVisible);
  65. }
  66. }
  67. [Fact]
  68. public void IsVisible_Should_Be_False_After_Close()
  69. {
  70. using (UnitTestApplication.Start(TestServices.StyledWindow))
  71. {
  72. var window = new Window();
  73. window.Show();
  74. window.Close();
  75. Assert.False(window.IsVisible);
  76. }
  77. }
  78. [Fact]
  79. public void IsVisible_Should_Be_False_After_Impl_Signals_Close()
  80. {
  81. var windowImpl = new Mock<IWindowImpl>();
  82. windowImpl.SetupProperty(x => x.Closed);
  83. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  84. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  85. var services = TestServices.StyledWindow.With(
  86. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  87. using (UnitTestApplication.Start(services))
  88. {
  89. var window = new Window();
  90. window.Show();
  91. windowImpl.Object.Closed();
  92. Assert.False(window.IsVisible);
  93. }
  94. }
  95. [Fact]
  96. public void Closing_Should_Only_Be_Invoked_Once()
  97. {
  98. using (UnitTestApplication.Start(TestServices.StyledWindow))
  99. {
  100. var window = new Window();
  101. var count = 0;
  102. window.Closing +=
  103. (sender, e) =>
  104. {
  105. count++;
  106. };
  107. window.Show();
  108. window.Close();
  109. Assert.Equal(1, count);
  110. }
  111. }
  112. [Theory]
  113. [InlineData(true)]
  114. [InlineData(false)]
  115. public void Child_windows_should_be_closed_before_parent(bool programaticClose)
  116. {
  117. using (UnitTestApplication.Start(TestServices.StyledWindow))
  118. {
  119. var window = new Window();
  120. var child = new Window();
  121. int count = 0;
  122. int windowClosing = 0;
  123. int childClosing = 0;
  124. int windowClosed = 0;
  125. int childClosed = 0;
  126. window.Closing += (sender, e) =>
  127. {
  128. count++;
  129. windowClosing = count;
  130. };
  131. child.Closing += (sender, e) =>
  132. {
  133. count++;
  134. childClosing = count;
  135. };
  136. window.Closed += (sender, e) =>
  137. {
  138. count++;
  139. windowClosed = count;
  140. };
  141. child.Closed += (sender, e) =>
  142. {
  143. count++;
  144. childClosed = count;
  145. };
  146. window.Show();
  147. child.Show(window);
  148. if (programaticClose)
  149. {
  150. window.Close();
  151. }
  152. else
  153. {
  154. var cancel = window.PlatformImpl.Closing();
  155. Assert.Equal(false, cancel);
  156. }
  157. Assert.Equal(2, windowClosing);
  158. Assert.Equal(1, childClosing);
  159. Assert.Equal(4, windowClosed);
  160. Assert.Equal(3, childClosed);
  161. }
  162. }
  163. [Theory]
  164. [InlineData(true)]
  165. [InlineData(false)]
  166. public void Child_windows_must_not_close_before_parent_has_chance_to_Cancel_OSCloseButton(bool programaticClose)
  167. {
  168. using (UnitTestApplication.Start(TestServices.StyledWindow))
  169. {
  170. var window = new Window();
  171. var child = new Window();
  172. int count = 0;
  173. int windowClosing = 0;
  174. int childClosing = 0;
  175. int windowClosed = 0;
  176. int childClosed = 0;
  177. window.Closing += (sender, e) =>
  178. {
  179. count++;
  180. windowClosing = count;
  181. e.Cancel = true;
  182. };
  183. child.Closing += (sender, e) =>
  184. {
  185. count++;
  186. childClosing = count;
  187. };
  188. window.Closed += (sender, e) =>
  189. {
  190. count++;
  191. windowClosed = count;
  192. };
  193. child.Closed += (sender, e) =>
  194. {
  195. count++;
  196. childClosed = count;
  197. };
  198. window.Show();
  199. child.Show(window);
  200. if (programaticClose)
  201. {
  202. window.Close();
  203. }
  204. else
  205. {
  206. var cancel = window.PlatformImpl.Closing();
  207. Assert.Equal(true, cancel);
  208. }
  209. Assert.Equal(2, windowClosing);
  210. Assert.Equal(1, childClosing);
  211. Assert.Equal(0, windowClosed);
  212. Assert.Equal(0, childClosed);
  213. }
  214. }
  215. [Fact]
  216. public void Showing_Should_Start_Renderer()
  217. {
  218. using (UnitTestApplication.Start(TestServices.StyledWindow))
  219. {
  220. var renderer = new Mock<IRenderer>();
  221. var target = new Window(CreateImpl(renderer));
  222. target.Show();
  223. renderer.Verify(x => x.Start(), Times.Once);
  224. }
  225. }
  226. [Fact]
  227. public void ShowDialog_Should_Start_Renderer()
  228. {
  229. using (UnitTestApplication.Start(TestServices.StyledWindow))
  230. {
  231. var parent = new Window();
  232. var renderer = new Mock<IRenderer>();
  233. var target = new Window(CreateImpl(renderer));
  234. parent.Show();
  235. target.ShowDialog<object>(parent);
  236. renderer.Verify(x => x.Start(), Times.Once);
  237. }
  238. }
  239. [Fact]
  240. public void ShowDialog_Should_Raise_Opened()
  241. {
  242. using (UnitTestApplication.Start(TestServices.StyledWindow))
  243. {
  244. var parent = new Window();
  245. var target = new Window();
  246. var raised = false;
  247. parent.Show();
  248. target.Opened += (s, e) => raised = true;
  249. target.ShowDialog<object>(parent);
  250. Assert.True(raised);
  251. }
  252. }
  253. [Fact]
  254. public void Hiding_Should_Stop_Renderer()
  255. {
  256. using (UnitTestApplication.Start(TestServices.StyledWindow))
  257. {
  258. var renderer = new Mock<IRenderer>();
  259. var target = new Window(CreateImpl(renderer));
  260. target.Show();
  261. target.Hide();
  262. renderer.Verify(x => x.Stop(), Times.Once);
  263. }
  264. }
  265. [Fact]
  266. public async Task ShowDialog_With_ValueType_Returns_Default_When_Closed()
  267. {
  268. using (UnitTestApplication.Start(TestServices.StyledWindow))
  269. {
  270. var parent = new Window();
  271. var windowImpl = new Mock<IWindowImpl>();
  272. windowImpl.SetupProperty(x => x.Closed);
  273. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  274. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  275. parent.Show();
  276. var target = new Window(windowImpl.Object);
  277. var task = target.ShowDialog<bool>(parent);
  278. windowImpl.Object.Closed();
  279. var result = await task;
  280. Assert.False(result);
  281. }
  282. }
  283. [Fact]
  284. public void Calling_Show_On_Closed_Window_Should_Throw()
  285. {
  286. using (UnitTestApplication.Start(TestServices.StyledWindow))
  287. {
  288. var target = new Window();
  289. target.Show();
  290. target.Close();
  291. var openedRaised = false;
  292. target.Opened += (s, e) => openedRaised = true;
  293. var ex = Assert.Throws<InvalidOperationException>(() => target.Show());
  294. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  295. Assert.False(openedRaised);
  296. }
  297. }
  298. [Fact]
  299. public async Task Calling_ShowDialog_On_Closed_Window_Should_Throw()
  300. {
  301. using (UnitTestApplication.Start(TestServices.StyledWindow))
  302. {
  303. var parent = new Window();
  304. var windowImpl = new Mock<IWindowImpl>();
  305. windowImpl.SetupProperty(x => x.Closed);
  306. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  307. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  308. parent.Show();
  309. var target = new Window(windowImpl.Object);
  310. var task = target.ShowDialog<bool>(parent);
  311. windowImpl.Object.Closed();
  312. await task;
  313. var openedRaised = false;
  314. target.Opened += (s, e) => openedRaised = true;
  315. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog<bool>(parent));
  316. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  317. Assert.False(openedRaised);
  318. }
  319. }
  320. [Fact]
  321. public void Calling_Show_With_Closed_Parent_Window_Should_Throw()
  322. {
  323. using (UnitTestApplication.Start(TestServices.StyledWindow))
  324. {
  325. var parent = new Window();
  326. var target = new Window();
  327. parent.Close();
  328. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
  329. Assert.Equal("Cannot show a window with a closed parent.", ex.Message);
  330. }
  331. }
  332. [Fact]
  333. public async Task Calling_ShowDialog_With_Closed_Parent_Window_Should_Throw()
  334. {
  335. using (UnitTestApplication.Start(TestServices.StyledWindow))
  336. {
  337. var parent = new Window();
  338. var target = new Window();
  339. parent.Close();
  340. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent));
  341. Assert.Equal("Cannot show a window with a closed owner.", ex.Message);
  342. }
  343. }
  344. [Fact]
  345. public void Calling_Show_With_Invisible_Parent_Window_Should_Throw()
  346. {
  347. using (UnitTestApplication.Start(TestServices.StyledWindow))
  348. {
  349. var parent = new Window();
  350. var target = new Window();
  351. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
  352. Assert.Equal("Cannot show window with non-visible parent.", ex.Message);
  353. }
  354. }
  355. [Fact]
  356. public async Task Calling_ShowDialog_With_Invisible_Parent_Window_Should_Throw()
  357. {
  358. using (UnitTestApplication.Start(TestServices.StyledWindow))
  359. {
  360. var parent = new Window();
  361. var target = new Window();
  362. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent));
  363. Assert.Equal("Cannot show window with non-visible parent.", ex.Message);
  364. }
  365. }
  366. [Fact]
  367. public void Calling_Show_With_Self_As_Parent_Window_Should_Throw()
  368. {
  369. using (UnitTestApplication.Start(TestServices.StyledWindow))
  370. {
  371. var target = new Window();
  372. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(target));
  373. Assert.Equal("A Window cannot be its own parent.", ex.Message);
  374. }
  375. }
  376. [Fact]
  377. public async Task Calling_ShowDialog_With_Self_As_Parent_Window_Should_Throw()
  378. {
  379. using (UnitTestApplication.Start(TestServices.StyledWindow))
  380. {
  381. var target = new Window();
  382. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(target));
  383. Assert.Equal("A Window cannot be its own owner.", ex.Message);
  384. }
  385. }
  386. [Fact]
  387. public void Hiding_Parent_Window_Should_Close_Children()
  388. {
  389. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  390. {
  391. var parent = new Window();
  392. var child = new Window();
  393. parent.Show();
  394. child.Show(parent);
  395. parent.Hide();
  396. Assert.False(parent.IsVisible);
  397. Assert.False(child.IsVisible);
  398. }
  399. }
  400. [Fact]
  401. public void Hiding_Parent_Window_Should_Close_Dialog_Children()
  402. {
  403. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  404. {
  405. var parent = new Window();
  406. var child = new Window();
  407. parent.Show();
  408. child.ShowDialog(parent);
  409. parent.Hide();
  410. Assert.False(parent.IsVisible);
  411. Assert.False(child.IsVisible);
  412. }
  413. }
  414. [Fact]
  415. public void Window_Should_Be_Centered_When_WindowStartupLocation_Is_CenterScreen()
  416. {
  417. var screen1 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 1040)), true);
  418. var screen2 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1366, 768)), new PixelRect(new PixelSize(1366, 728)), false);
  419. var screens = new Mock<IScreenImpl>();
  420. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object, screen2.Object });
  421. screens.Setup(x => x.ScreenFromPoint(It.IsAny<PixelPoint>())).Returns(screen1.Object);
  422. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  423. windowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  424. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  425. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  426. windowImpl.Setup(x => x.Screen).Returns(screens.Object);
  427. using (UnitTestApplication.Start(TestServices.StyledWindow))
  428. {
  429. var window = new Window(windowImpl.Object);
  430. window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  431. window.Position = new PixelPoint(60, 40);
  432. window.Show();
  433. var expectedPosition = new PixelPoint(
  434. (int)(screen1.Object.WorkingArea.Size.Width / 2 - window.ClientSize.Width / 2),
  435. (int)(screen1.Object.WorkingArea.Size.Height / 2 - window.ClientSize.Height / 2));
  436. Assert.Equal(window.Position, expectedPosition);
  437. }
  438. }
  439. [Fact]
  440. public void Window_Should_Be_Sized_To_MinSize_If_InitialSize_Less_Than_MinSize()
  441. {
  442. var screen1 = new Mock<Screen>(1.75, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 966)), true);
  443. var screens = new Mock<IScreenImpl>();
  444. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object });
  445. screens.Setup(x => x.ScreenFromPoint(It.IsAny<PixelPoint>())).Returns(screen1.Object);
  446. var windowImpl = MockWindowingPlatform.CreateWindowMock(400, 300);
  447. windowImpl.Setup(x => x.DesktopScaling).Returns(1.75);
  448. windowImpl.Setup(x => x.RenderScaling).Returns(1.75);
  449. windowImpl.Setup(x => x.Screen).Returns(screens.Object);
  450. using (UnitTestApplication.Start(TestServices.StyledWindow))
  451. {
  452. var window = new Window(windowImpl.Object);
  453. window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  454. window.MinWidth = 720;
  455. window.MinHeight = 480;
  456. window.Show();
  457. Assert.Equal(new PixelPoint(330, 63), window.Position);
  458. Assert.Equal(new Size(720, 480), window.Bounds.Size);
  459. }
  460. }
  461. [Fact]
  462. public void Window_Should_Be_Centered_Relative_To_Owner_When_WindowStartupLocation_Is_CenterOwner()
  463. {
  464. var parentWindowImpl = MockWindowingPlatform.CreateWindowMock();
  465. parentWindowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  466. parentWindowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
  467. parentWindowImpl.Setup(x => x.DesktopScaling).Returns(1);
  468. parentWindowImpl.Setup(x => x.RenderScaling).Returns(1);
  469. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  470. windowImpl.Setup(x => x.ClientSize).Returns(new Size(320, 200));
  471. windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
  472. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  473. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  474. var parentWindowServices = TestServices.StyledWindow.With(
  475. windowingPlatform: new MockWindowingPlatform(() => parentWindowImpl.Object));
  476. var windowServices = TestServices.StyledWindow.With(
  477. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  478. using (UnitTestApplication.Start(parentWindowServices))
  479. {
  480. var parentWindow = new Window();
  481. parentWindow.Position = new PixelPoint(60, 40);
  482. parentWindow.Show();
  483. using (UnitTestApplication.Start(windowServices))
  484. {
  485. var window = new Window();
  486. window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  487. window.Position = new PixelPoint(60, 40);
  488. window.ShowDialog(parentWindow);
  489. var expectedPosition = new PixelPoint(
  490. (int)(parentWindow.Position.X + parentWindow.ClientSize.Width / 2 - window.ClientSize.Width / 2),
  491. (int)(parentWindow.Position.Y + parentWindow.ClientSize.Height / 2 - window.ClientSize.Height / 2));
  492. Assert.Equal(window.Position, expectedPosition);
  493. }
  494. }
  495. }
  496. public class SizingTests
  497. {
  498. [Fact]
  499. public void Child_Should_Be_Measured_With_Width_And_Height_If_SizeToContent_Is_Manual()
  500. {
  501. using (UnitTestApplication.Start(TestServices.StyledWindow))
  502. {
  503. var child = new ChildControl();
  504. var target = new Window
  505. {
  506. Width = 100,
  507. Height = 50,
  508. SizeToContent = SizeToContent.Manual,
  509. Content = child
  510. };
  511. Show(target);
  512. Assert.Equal(1, child.MeasureSizes.Count);
  513. Assert.Equal(new Size(100, 50), child.MeasureSizes[0]);
  514. }
  515. }
  516. [Fact]
  517. public void Child_Should_Be_Measured_With_ClientSize_If_SizeToContent_Is_Manual_And_No_Width_Height_Specified()
  518. {
  519. using (UnitTestApplication.Start(TestServices.StyledWindow))
  520. {
  521. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  522. windowImpl.Setup(x => x.ClientSize).Returns(new Size(550, 450));
  523. var child = new ChildControl();
  524. var target = new Window(windowImpl.Object)
  525. {
  526. SizeToContent = SizeToContent.Manual,
  527. Content = child
  528. };
  529. Show(target);
  530. Assert.Equal(1, child.MeasureSizes.Count);
  531. Assert.Equal(new Size(550, 450), child.MeasureSizes[0]);
  532. }
  533. }
  534. [Fact]
  535. public void Child_Should_Be_Measured_With_MaxAutoSizeHint_If_SizeToContent_Is_WidthAndHeight()
  536. {
  537. using (UnitTestApplication.Start(TestServices.StyledWindow))
  538. {
  539. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  540. windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1200, 1000));
  541. var child = new ChildControl();
  542. var target = new Window(windowImpl.Object)
  543. {
  544. Width = 100,
  545. Height = 50,
  546. SizeToContent = SizeToContent.WidthAndHeight,
  547. Content = child
  548. };
  549. target.Show();
  550. Assert.Equal(1, child.MeasureSizes.Count);
  551. Assert.Equal(new Size(1200, 1000), child.MeasureSizes[0]);
  552. }
  553. }
  554. [Fact]
  555. public void Should_Not_Have_Offset_On_Bounds_When_Content_Larger_Than_Max_Window_Size()
  556. {
  557. // Issue #3784.
  558. using (UnitTestApplication.Start(TestServices.StyledWindow))
  559. {
  560. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  561. var clientSize = new Size(200, 200);
  562. var maxClientSize = new Size(480, 480);
  563. windowImpl.Setup(x => x.Resize(It.IsAny<Size>(), It.IsAny<PlatformResizeReason>()))
  564. .Callback<Size, PlatformResizeReason>((size, reason) =>
  565. {
  566. clientSize = size.Constrain(maxClientSize);
  567. windowImpl.Object.Resized?.Invoke(clientSize, reason);
  568. });
  569. windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize);
  570. var child = new Canvas
  571. {
  572. Width = 400,
  573. Height = 800,
  574. };
  575. var target = new Window(windowImpl.Object)
  576. {
  577. SizeToContent = SizeToContent.WidthAndHeight,
  578. Content = child
  579. };
  580. Show(target);
  581. Assert.Equal(new Size(400, 480), target.Bounds.Size);
  582. // Issue #3784 causes this to be (0, 160) which makes no sense as Window has no
  583. // parent control to be offset against.
  584. Assert.Equal(new Point(0, 0), target.Bounds.Position);
  585. }
  586. }
  587. [Fact]
  588. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_Manual()
  589. {
  590. using (UnitTestApplication.Start(TestServices.StyledWindow))
  591. {
  592. var child = new Canvas
  593. {
  594. Width = 400,
  595. Height = 800,
  596. };
  597. var target = new Window()
  598. {
  599. SizeToContent = SizeToContent.Manual,
  600. Content = child
  601. };
  602. Show(target);
  603. // Values come from MockWindowingPlatform defaults.
  604. Assert.Equal(800, target.Width);
  605. Assert.Equal(600, target.Height);
  606. }
  607. }
  608. [Fact]
  609. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_WidthAndHeight()
  610. {
  611. using (UnitTestApplication.Start(TestServices.StyledWindow))
  612. {
  613. var child = new Canvas
  614. {
  615. Width = 400,
  616. Height = 800,
  617. };
  618. var target = new Window()
  619. {
  620. SizeToContent = SizeToContent.WidthAndHeight,
  621. Content = child
  622. };
  623. target.GetObservable(Window.WidthProperty).Subscribe(x => { });
  624. Show(target);
  625. Assert.Equal(400, target.Width);
  626. Assert.Equal(800, target.Height);
  627. }
  628. }
  629. [Fact]
  630. public void MaxWidth_And_MaxHeight_Should_Be_Respected_With_SizeToContent_WidthAndHeight()
  631. {
  632. using (UnitTestApplication.Start(TestServices.StyledWindow))
  633. {
  634. var child = new ChildControl();
  635. var target = new Window()
  636. {
  637. SizeToContent = SizeToContent.WidthAndHeight,
  638. MaxWidth = 300,
  639. MaxHeight = 700,
  640. Content = child,
  641. };
  642. Show(target);
  643. Assert.Equal(new[] { new Size(300, 700) }, child.MeasureSizes);
  644. }
  645. }
  646. [Fact]
  647. public void SizeToContent_Should_Not_Be_Lost_On_Show()
  648. {
  649. using (UnitTestApplication.Start(TestServices.StyledWindow))
  650. {
  651. var child = new Canvas
  652. {
  653. Width = 400,
  654. Height = 800,
  655. };
  656. var target = new Window()
  657. {
  658. SizeToContent = SizeToContent.WidthAndHeight,
  659. Content = child
  660. };
  661. Show(target);
  662. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  663. }
  664. }
  665. [Fact]
  666. public void SizeToContent_Should_Not_Be_Lost_On_Scaling_Change()
  667. {
  668. using (UnitTestApplication.Start(TestServices.StyledWindow))
  669. {
  670. var child = new Canvas
  671. {
  672. Width = 209,
  673. Height = 117,
  674. };
  675. var target = new Window()
  676. {
  677. SizeToContent = SizeToContent.WidthAndHeight,
  678. Content = child
  679. };
  680. Show(target);
  681. // Size before and after DPI change is a real-world example, with size after DPI
  682. // change coming from Win32 WM_DPICHANGED.
  683. target.PlatformImpl.ScalingChanged(1.5);
  684. target.PlatformImpl.Resized(
  685. new Size(210.66666666666666, 118.66666666666667),
  686. PlatformResizeReason.DpiChange);
  687. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  688. }
  689. }
  690. [Fact]
  691. public void Width_Height_Should_Be_Updated_When_SizeToContent_Is_WidthAndHeight()
  692. {
  693. using (UnitTestApplication.Start(TestServices.StyledWindow))
  694. {
  695. var child = new Canvas
  696. {
  697. Width = 400,
  698. Height = 800,
  699. };
  700. var target = new Window()
  701. {
  702. SizeToContent = SizeToContent.WidthAndHeight,
  703. Content = child
  704. };
  705. Show(target);
  706. Assert.Equal(400, target.Width);
  707. Assert.Equal(800, target.Height);
  708. child.Width = 410;
  709. target.LayoutManager.ExecuteLayoutPass();
  710. Assert.Equal(410, target.Width);
  711. Assert.Equal(800, target.Height);
  712. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  713. }
  714. }
  715. [Fact]
  716. public void Setting_Width_Should_Resize_WindowImpl()
  717. {
  718. // Issue #3796
  719. using (UnitTestApplication.Start(TestServices.StyledWindow))
  720. {
  721. var target = new Window()
  722. {
  723. Width = 400,
  724. Height = 800,
  725. };
  726. Show(target);
  727. Assert.Equal(400, target.Width);
  728. Assert.Equal(800, target.Height);
  729. target.Width = 410;
  730. target.LayoutManager.ExecuteLayoutPass();
  731. var windowImpl = Mock.Get(target.PlatformImpl);
  732. windowImpl.Verify(x => x.Resize(new Size(410, 800), PlatformResizeReason.Application));
  733. Assert.Equal(410, target.Width);
  734. }
  735. }
  736. [Fact]
  737. public void User_Resize_Of_Window_Width_Should_Reset_SizeToContent()
  738. {
  739. using (UnitTestApplication.Start(TestServices.StyledWindow))
  740. {
  741. var target = new Window()
  742. {
  743. SizeToContent = SizeToContent.WidthAndHeight,
  744. Content = new Canvas
  745. {
  746. Width = 400,
  747. Height = 800,
  748. },
  749. };
  750. Show(target);
  751. Assert.Equal(400, target.Width);
  752. Assert.Equal(800, target.Height);
  753. target.PlatformImpl.Resized(new Size(410, 800), PlatformResizeReason.User);
  754. Assert.Equal(410, target.Width);
  755. Assert.Equal(800, target.Height);
  756. Assert.Equal(SizeToContent.Height, target.SizeToContent);
  757. }
  758. }
  759. [Fact]
  760. public void User_Resize_Of_Window_Height_Should_Reset_SizeToContent()
  761. {
  762. using (UnitTestApplication.Start(TestServices.StyledWindow))
  763. {
  764. var target = new Window()
  765. {
  766. SizeToContent = SizeToContent.WidthAndHeight,
  767. Content = new Canvas
  768. {
  769. Width = 400,
  770. Height = 800,
  771. },
  772. };
  773. Show(target);
  774. Assert.Equal(400, target.Width);
  775. Assert.Equal(800, target.Height);
  776. target.PlatformImpl.Resized(new Size(400, 810), PlatformResizeReason.User);
  777. Assert.Equal(400, target.Width);
  778. Assert.Equal(810, target.Height);
  779. Assert.Equal(SizeToContent.Width, target.SizeToContent);
  780. }
  781. }
  782. [Fact]
  783. public void Window_Resize_Should_Not_Reset_SizeToContent_If_CanResize_False()
  784. {
  785. using (UnitTestApplication.Start(TestServices.StyledWindow))
  786. {
  787. var target = new Window()
  788. {
  789. SizeToContent = SizeToContent.WidthAndHeight,
  790. CanResize = false,
  791. Content = new Canvas
  792. {
  793. Width = 400,
  794. Height = 800,
  795. },
  796. };
  797. Show(target);
  798. Assert.Equal(400, target.Width);
  799. Assert.Equal(800, target.Height);
  800. target.PlatformImpl.Resized(new Size(410, 810), PlatformResizeReason.Unspecified);
  801. Assert.Equal(400, target.Width);
  802. Assert.Equal(800, target.Height);
  803. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  804. }
  805. }
  806. protected virtual void Show(Window window)
  807. {
  808. window.Show();
  809. }
  810. }
  811. public class DialogSizingTests : SizingTests
  812. {
  813. protected override void Show(Window window)
  814. {
  815. var owner = new Window();
  816. owner.Show();
  817. window.ShowDialog(owner);
  818. }
  819. }
  820. private IWindowImpl CreateImpl(Mock<IRenderer> renderer)
  821. {
  822. return Mock.Of<IWindowImpl>(x =>
  823. x.RenderScaling == 1 &&
  824. x.CreateRenderer(It.IsAny<IRenderRoot>()) == renderer.Object);
  825. }
  826. private class ChildControl : Control
  827. {
  828. public List<Size> MeasureSizes { get; } = new List<Size>();
  829. protected override Size MeasureOverride(Size availableSize)
  830. {
  831. MeasureSizes.Add(availableSize);
  832. return base.MeasureOverride(availableSize);
  833. }
  834. }
  835. }
  836. }