DynamicResourceExtensionTests.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. using System;
  2. using System.Linq;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.Presenters;
  5. using Avalonia.Controls.Templates;
  6. using Avalonia.Markup.Data;
  7. using Avalonia.Media;
  8. using Avalonia.Styling;
  9. using Avalonia.UnitTests;
  10. using Avalonia.VisualTree;
  11. using Xunit;
  12. namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
  13. {
  14. public class DynamicResourceExtensionTests : XamlTestBase
  15. {
  16. [Fact]
  17. public void DynamicResource_Can_Be_Assigned_To_Property()
  18. {
  19. var xaml = @"
  20. <UserControl xmlns='https://github.com/avaloniaui'
  21. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  22. <UserControl.Resources>
  23. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  24. </UserControl.Resources>
  25. <Border Name='border' Background='{DynamicResource brush}'/>
  26. </UserControl>";
  27. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  28. var border = userControl.FindControl<Border>("border");
  29. DelayedBinding.ApplyBindings(border);
  30. var brush = (SolidColorBrush)border.Background;
  31. Assert.Equal(0xff506070, brush.Color.ToUint32());
  32. }
  33. [Fact]
  34. public void DynamicResource_Can_Be_Assigned_To_Attached_Property()
  35. {
  36. var xaml = @"
  37. <UserControl xmlns='https://github.com/avaloniaui'
  38. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  39. <UserControl.Resources>
  40. <x:Int32 x:Key='col'>5</x:Int32>
  41. </UserControl.Resources>
  42. <Border Name='border' Grid.Column='{DynamicResource col}'/>
  43. </UserControl>";
  44. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  45. var border = userControl.FindControl<Border>("border");
  46. DelayedBinding.ApplyBindings(border);
  47. Assert.Equal(5, Grid.GetColumn(border));
  48. }
  49. [Fact]
  50. public void DynamicResource_From_Style_Can_Be_Assigned_To_Property()
  51. {
  52. var xaml = @"
  53. <UserControl xmlns='https://github.com/avaloniaui'
  54. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  55. <UserControl.Styles>
  56. <Style>
  57. <Style.Resources>
  58. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  59. </Style.Resources>
  60. </Style>
  61. </UserControl.Styles>
  62. <Border Name='border' Background='{DynamicResource brush}'/>
  63. </UserControl>";
  64. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  65. var border = userControl.FindControl<Border>("border");
  66. DelayedBinding.ApplyBindings(border);
  67. var brush = (SolidColorBrush)border.Background;
  68. Assert.Equal(0xff506070, brush.Color.ToUint32());
  69. }
  70. [Fact]
  71. public void DynamicResource_From_MergedDictionary_Can_Be_Assigned_To_Property()
  72. {
  73. var xaml = @"
  74. <UserControl xmlns='https://github.com/avaloniaui'
  75. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  76. <UserControl.Resources>
  77. <ResourceDictionary>
  78. <ResourceDictionary.MergedDictionaries>
  79. <ResourceDictionary>
  80. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  81. </ResourceDictionary>
  82. </ResourceDictionary.MergedDictionaries>
  83. </ResourceDictionary>
  84. </UserControl.Resources>
  85. <Border Name='border' Background='{DynamicResource brush}'/>
  86. </UserControl>";
  87. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  88. var border = userControl.FindControl<Border>("border");
  89. DelayedBinding.ApplyBindings(border);
  90. var brush = (SolidColorBrush)border.Background;
  91. Assert.Equal(0xff506070, brush.Color.ToUint32());
  92. }
  93. [Fact]
  94. public void DynamicResource_From_MergedDictionary_In_Style_Can_Be_Assigned_To_Property()
  95. {
  96. var xaml = @"
  97. <UserControl xmlns='https://github.com/avaloniaui'
  98. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  99. <UserControl.Styles>
  100. <Style>
  101. <Style.Resources>
  102. <ResourceDictionary>
  103. <ResourceDictionary.MergedDictionaries>
  104. <ResourceDictionary>
  105. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  106. </ResourceDictionary>
  107. </ResourceDictionary.MergedDictionaries>
  108. </ResourceDictionary>
  109. </Style.Resources>
  110. </Style>
  111. </UserControl.Styles>
  112. <Border Name='border' Background='{DynamicResource brush}'/>
  113. </UserControl>";
  114. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  115. var border = userControl.FindControl<Border>("border");
  116. DelayedBinding.ApplyBindings(border);
  117. var brush = (SolidColorBrush)border.Background;
  118. Assert.Equal(0xff506070, brush.Color.ToUint32());
  119. }
  120. [Fact]
  121. public void DynamicResource_From_Application_Can_Be_Assigned_To_Property_In_Window()
  122. {
  123. using (StyledWindow())
  124. {
  125. Application.Current.Resources.Add("brush", new SolidColorBrush(0xff506070));
  126. var xaml = @"
  127. <Window xmlns='https://github.com/avaloniaui'
  128. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  129. <Border Name='border' Background='{DynamicResource brush}'/>
  130. </Window>";
  131. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  132. var border = window.FindControl<Border>("border");
  133. var brush = (SolidColorBrush)border.Background;
  134. Assert.Equal(0xff506070, brush.Color.ToUint32());
  135. }
  136. }
  137. [Fact]
  138. public void DynamicResource_From_Application_Can_Be_Assigned_To_Property_In_UserControl()
  139. {
  140. using (UnitTestApplication.Start(TestServices.StyledWindow))
  141. {
  142. Application.Current.Resources.Add("brush", new SolidColorBrush(0xff506070));
  143. var xaml = @"
  144. <UserControl xmlns='https://github.com/avaloniaui'
  145. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  146. <Border Name='border' Background='{DynamicResource brush}'/>
  147. </UserControl>";
  148. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  149. var border = userControl.FindControl<Border>("border");
  150. // We don't actually know where the global styles are until we attach the control
  151. // to a window, as Window has StylingParent set to Application.
  152. var window = new Window { Content = userControl };
  153. window.Show();
  154. var brush = (SolidColorBrush)border.Background;
  155. Assert.Equal(0xff506070, brush.Color.ToUint32());
  156. }
  157. }
  158. [Fact]
  159. public void DynamicResource_Can_Be_Assigned_To_Setter()
  160. {
  161. using (StyledWindow())
  162. {
  163. var xaml = @"
  164. <Window xmlns='https://github.com/avaloniaui'
  165. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  166. <Window.Resources>
  167. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  168. </Window.Resources>
  169. <Window.Styles>
  170. <Style Selector='Button'>
  171. <Setter Property='Background' Value='{DynamicResource brush}'/>
  172. </Style>
  173. </Window.Styles>
  174. <Button Name='button'/>
  175. </Window>";
  176. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  177. var button = window.FindControl<Button>("button");
  178. var brush = (SolidColorBrush)button.Background;
  179. Assert.Equal(0xff506070, brush.Color.ToUint32());
  180. }
  181. }
  182. [Fact]
  183. public void DynamicResource_From_Style_Can_Be_Assigned_To_Setter()
  184. {
  185. using (StyledWindow())
  186. {
  187. var xaml = @"
  188. <Window xmlns='https://github.com/avaloniaui'
  189. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  190. <Window.Styles>
  191. <Style>
  192. <Style.Resources>
  193. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  194. </Style.Resources>
  195. </Style>
  196. <Style Selector='Button'>
  197. <Setter Property='Background' Value='{DynamicResource brush}'/>
  198. </Style>
  199. </Window.Styles>
  200. <Button Name='button'/>
  201. </Window>";
  202. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  203. var button = window.FindControl<Button>("button");
  204. var brush = (SolidColorBrush)button.Background;
  205. Assert.Equal(0xff506070, brush.Color.ToUint32());
  206. }
  207. }
  208. [Fact]
  209. public void DynamicResource_Can_Be_Assigned_To_Setter_In_Styles_File()
  210. {
  211. var styleXaml = @"
  212. <Styles xmlns='https://github.com/avaloniaui'
  213. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  214. <Styles.Resources>
  215. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  216. </Styles.Resources>
  217. <Style Selector='Border'>
  218. <Setter Property='Background' Value='{DynamicResource brush}'/>
  219. </Style>
  220. </Styles>";
  221. using (StyledWindow(assets: ("test:style.xaml", styleXaml)))
  222. {
  223. var xaml = @"
  224. <Window xmlns='https://github.com/avaloniaui'
  225. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  226. <Window.Styles>
  227. <StyleInclude Source='test:style.xaml'/>
  228. </Window.Styles>
  229. <Border Name='border'/>
  230. </Window>";
  231. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  232. var border = window.FindControl<Border>("border");
  233. var brush = (SolidColorBrush)border.Background;
  234. Assert.Equal(0xff506070, brush.Color.ToUint32());
  235. }
  236. }
  237. [Fact]
  238. public void DynamicResource_Can_Be_Assigned_To_Property_In_ControlTemplate_In_Styles_File()
  239. {
  240. var styleXaml = @"
  241. <Styles xmlns='https://github.com/avaloniaui'
  242. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  243. <Styles.Resources>
  244. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  245. </Styles.Resources>
  246. <Style Selector='Button'>
  247. <Setter Property='Template'>
  248. <ControlTemplate>
  249. <Border Name='border' Background='{DynamicResource brush}'/>
  250. </ControlTemplate>
  251. </Setter>
  252. </Style>
  253. </Styles>";
  254. using (StyledWindow(assets: ("test:style.xaml", styleXaml)))
  255. {
  256. var xaml = @"
  257. <Window xmlns='https://github.com/avaloniaui'
  258. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  259. <Window.Styles>
  260. <StyleInclude Source='test:style.xaml'/>
  261. </Window.Styles>
  262. <Button Name='button'/>
  263. </Window>";
  264. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  265. var button = window.FindControl<Button>("button");
  266. window.Show();
  267. var border = (Border)button.GetVisualChildren().Single();
  268. var brush = (SolidColorBrush)border.Background;
  269. Assert.Equal(0xff506070, brush.Color.ToUint32());
  270. }
  271. }
  272. [Fact]
  273. public void DynamicResource_Can_Be_Assigned_To_Resource_Property()
  274. {
  275. var xaml = @"
  276. <UserControl xmlns='https://github.com/avaloniaui'
  277. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  278. <UserControl.Resources>
  279. <Color x:Key='color'>#ff506070</Color>
  280. <SolidColorBrush x:Key='brush' Color='{DynamicResource color}'/>
  281. </UserControl.Resources>
  282. <Border Name='border' Background='{DynamicResource brush}'/>
  283. </UserControl>";
  284. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  285. var border = userControl.FindControl<Border>("border");
  286. DelayedBinding.ApplyBindings(border);
  287. var brush = (SolidColorBrush)border.Background;
  288. Assert.Equal(0xff506070, brush.Color.ToUint32());
  289. }
  290. [Fact]
  291. public void DynamicResource_Can_Be_Assigned_To_ItemTemplate_Property()
  292. {
  293. var xaml = @"
  294. <UserControl xmlns='https://github.com/avaloniaui'
  295. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  296. <UserControl.Resources>
  297. <DataTemplate x:Key='PurpleData'>
  298. <TextBlock Text='{Binding Name}' Background='Purple'/>
  299. </DataTemplate>
  300. </UserControl.Resources>
  301. <ListBox Name='listBox' ItemTemplate='{DynamicResource PurpleData}'/>
  302. </UserControl>";
  303. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  304. var listBox = userControl.FindControl<ListBox>("listBox");
  305. DelayedBinding.ApplyBindings(listBox);
  306. Assert.NotNull(listBox.ItemTemplate);
  307. }
  308. [Fact]
  309. public void DynamicResource_Tracks_Added_Resource()
  310. {
  311. var xaml = @"
  312. <UserControl xmlns='https://github.com/avaloniaui'
  313. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  314. <Border Name='border' Background='{DynamicResource brush}'/>
  315. </UserControl>";
  316. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  317. var border = userControl.FindControl<Border>("border");
  318. DelayedBinding.ApplyBindings(border);
  319. Assert.Null(border.Background);
  320. userControl.Resources.Add("brush", new SolidColorBrush(0xff506070));
  321. var brush = (SolidColorBrush)border.Background;
  322. Assert.NotNull(brush);
  323. Assert.Equal(0xff506070, brush.Color.ToUint32());
  324. }
  325. [Fact]
  326. public void DynamicResource_Tracks_Added_Style_Resource()
  327. {
  328. var xaml = @"
  329. <UserControl xmlns='https://github.com/avaloniaui'
  330. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  331. <Border Name='border' Background='{DynamicResource brush}'/>
  332. </UserControl>";
  333. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  334. var border = userControl.FindControl<Border>("border");
  335. DelayedBinding.ApplyBindings(border);
  336. Assert.Null(border.Background);
  337. userControl.Styles.Resources.Add("brush", new SolidColorBrush(0xff506070));
  338. var brush = (SolidColorBrush)border.Background;
  339. Assert.NotNull(brush);
  340. Assert.Equal(0xff506070, brush.Color.ToUint32());
  341. }
  342. [Fact]
  343. public void DynamicResource_Tracks_Added_Nested_Style_Resource()
  344. {
  345. var xaml = @"
  346. <UserControl xmlns='https://github.com/avaloniaui'
  347. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  348. <UserControl.Styles>
  349. <Style>
  350. </Style>
  351. </UserControl.Styles>
  352. <Border Name='border' Background='{DynamicResource brush}'/>
  353. </UserControl>";
  354. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  355. var border = userControl.FindControl<Border>("border");
  356. DelayedBinding.ApplyBindings(border);
  357. Assert.Null(border.Background);
  358. ((Style)userControl.Styles[0]).Resources.Add("brush", new SolidColorBrush(0xff506070));
  359. var brush = (SolidColorBrush)border.Background;
  360. Assert.NotNull(brush);
  361. Assert.Equal(0xff506070, brush.Color.ToUint32());
  362. }
  363. [Fact]
  364. public void DynamicResource_Tracks_Added_MergedResource()
  365. {
  366. var xaml = @"
  367. <UserControl xmlns='https://github.com/avaloniaui'
  368. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  369. <UserControl.Resources>
  370. <ResourceDictionary>
  371. <ResourceDictionary.MergedDictionaries>
  372. <ResourceDictionary/>
  373. </ResourceDictionary.MergedDictionaries>
  374. </ResourceDictionary>
  375. </UserControl.Resources>
  376. <Border Name='border' Background='{DynamicResource brush}'/>
  377. </UserControl>";
  378. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  379. var border = userControl.FindControl<Border>("border");
  380. DelayedBinding.ApplyBindings(border);
  381. Assert.Null(border.Background);
  382. ((IResourceDictionary)userControl.Resources.MergedDictionaries[0]).Add("brush", new SolidColorBrush(0xff506070));
  383. var brush = (SolidColorBrush)border.Background;
  384. Assert.NotNull(brush);
  385. Assert.Equal(0xff506070, brush.Color.ToUint32());
  386. }
  387. [Fact]
  388. public void DynamicResource_Tracks_Added_MergedResource_Dictionary()
  389. {
  390. var xaml = @"
  391. <UserControl xmlns='https://github.com/avaloniaui'
  392. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  393. <Border Name='border' Background='{DynamicResource brush}'/>
  394. </UserControl>";
  395. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  396. var border = userControl.FindControl<Border>("border");
  397. DelayedBinding.ApplyBindings(border);
  398. Assert.Null(border.Background);
  399. var dictionary = new ResourceDictionary
  400. {
  401. { "brush", new SolidColorBrush(0xff506070) },
  402. };
  403. userControl.Resources.MergedDictionaries.Add(dictionary);
  404. var brush = (SolidColorBrush)border.Background;
  405. Assert.NotNull(brush);
  406. Assert.Equal(0xff506070, brush.Color.ToUint32());
  407. }
  408. [Fact]
  409. public void DynamicResource_Tracks_Added_Style_MergedResource_Dictionary()
  410. {
  411. var xaml = @"
  412. <UserControl xmlns='https://github.com/avaloniaui'
  413. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  414. <UserControl.Styles>
  415. <Style>
  416. </Style>
  417. </UserControl.Styles>
  418. <Border Name='border' Background='{DynamicResource brush}'/>
  419. </UserControl>";
  420. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  421. var border = userControl.FindControl<Border>("border");
  422. DelayedBinding.ApplyBindings(border);
  423. Assert.Null(border.Background);
  424. var dictionary = new ResourceDictionary
  425. {
  426. { "brush", new SolidColorBrush(0xff506070) },
  427. };
  428. ((Style)userControl.Styles[0]).Resources.MergedDictionaries.Add(dictionary);
  429. var brush = (SolidColorBrush)border.Background;
  430. Assert.NotNull(brush);
  431. Assert.Equal(0xff506070, brush.Color.ToUint32());
  432. }
  433. [Fact]
  434. public void DynamicResource_Can_Be_Found_Across_Xaml_Style_Files()
  435. {
  436. var style1Xaml = @"
  437. <Style xmlns='https://github.com/avaloniaui'
  438. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  439. <Style.Resources>
  440. <Color x:Key='Red'>Red</Color>
  441. </Style.Resources>
  442. </Style>";
  443. var style2Xaml = @"
  444. <Style xmlns='https://github.com/avaloniaui'
  445. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  446. <Style.Resources>
  447. <SolidColorBrush x:Key='RedBrush' Color='{DynamicResource Red}'/>
  448. </Style.Resources>
  449. </Style>";
  450. using (StyledWindow(
  451. ("test:style1.xaml", style1Xaml),
  452. ("test:style2.xaml", style2Xaml)))
  453. {
  454. var xaml = @"
  455. <Window xmlns='https://github.com/avaloniaui'
  456. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  457. <Window.Styles>
  458. <StyleInclude Source='test:style1.xaml'/>
  459. <StyleInclude Source='test:style2.xaml'/>
  460. </Window.Styles>
  461. <Border Name='border' Background='{DynamicResource RedBrush}'/>
  462. </Window>";
  463. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  464. var border = window.FindControl<Border>("border");
  465. var borderBrush = (ISolidColorBrush)border.Background;
  466. Assert.NotNull(borderBrush);
  467. Assert.Equal(0xffff0000, borderBrush.Color.ToUint32());
  468. }
  469. }
  470. [Fact]
  471. public void DynamicResource_Can_Be_Found_In_Nested_Style_File()
  472. {
  473. var style1Xaml = @"
  474. <Styles xmlns='https://github.com/avaloniaui'
  475. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  476. <StyleInclude Source='test:style2.xaml'/>
  477. </Styles>";
  478. var style2Xaml = @"
  479. <Style xmlns='https://github.com/avaloniaui'
  480. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  481. <Style.Resources>
  482. <Color x:Key='Red'>Red</Color>
  483. <SolidColorBrush x:Key='RedBrush' Color='{DynamicResource Red}'/>
  484. </Style.Resources>
  485. </Style>";
  486. using (StyledWindow(
  487. ("test:style1.xaml", style1Xaml),
  488. ("test:style2.xaml", style2Xaml)))
  489. {
  490. var xaml = @"
  491. <Window xmlns='https://github.com/avaloniaui'
  492. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  493. <Window.Styles>
  494. <StyleInclude Source='test:style1.xaml'/>
  495. </Window.Styles>
  496. <Border Name='border' Background='{DynamicResource RedBrush}'/>
  497. </Window>";
  498. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  499. var border = window.FindControl<Border>("border");
  500. var borderBrush = (ISolidColorBrush)border.Background;
  501. Assert.NotNull(borderBrush);
  502. Assert.Equal(0xffff0000, borderBrush.Color.ToUint32());
  503. }
  504. }
  505. [Fact]
  506. public void Control_Property_Is_Updated_When_Parent_Is_Changed()
  507. {
  508. using (StyledWindow())
  509. {
  510. var xaml = @"
  511. <Window xmlns='https://github.com/avaloniaui'
  512. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  513. <Window.Resources>
  514. <SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
  515. </Window.Resources>
  516. <Border Name='border' Background='{DynamicResource brush}'/>
  517. </Window>";
  518. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  519. var border = window.FindControl<Border>("border");
  520. DelayedBinding.ApplyBindings(border);
  521. var brush = (SolidColorBrush)border.Background;
  522. Assert.Equal(0xff506070, brush.Color.ToUint32());
  523. window.Content = null;
  524. Assert.Null(border.Background);
  525. window.Content = border;
  526. brush = (SolidColorBrush)border.Background;
  527. Assert.Equal(0xff506070, brush.Color.ToUint32());
  528. }
  529. }
  530. [Fact]
  531. public void Resource_With_DynamicResource_Is_Updated_When_Added_To_Parent()
  532. {
  533. var xaml = @"
  534. <UserControl xmlns='https://github.com/avaloniaui'
  535. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  536. <UserControl.Resources>
  537. <SolidColorBrush x:Key='brush' Color='{DynamicResource color}'/>
  538. </UserControl.Resources>
  539. <Border Name='border' Background='{DynamicResource brush}'/>
  540. </UserControl>";
  541. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  542. var border = userControl.FindControl<Border>("border");
  543. DelayedBinding.ApplyBindings(border);
  544. var brush = (SolidColorBrush)border.Background;
  545. Assert.Equal(0u, brush.Color.ToUint32());
  546. brush.GetObservable(SolidColorBrush.ColorProperty).Subscribe(_ => { });
  547. using (UnitTestApplication.Start(TestServices.StyledWindow))
  548. {
  549. var window = new Window
  550. {
  551. Resources =
  552. {
  553. { "color", Colors.Red }
  554. },
  555. Content = userControl,
  556. };
  557. window.Show();
  558. Assert.Equal(Colors.Red, brush.Color);
  559. }
  560. }
  561. [Fact]
  562. public void MergedDictionary_Resource_With_DynamicResource_Is_Updated_When_Added_To_Parent()
  563. {
  564. var xaml = @"
  565. <UserControl xmlns='https://github.com/avaloniaui'
  566. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  567. <UserControl.Resources>
  568. <ResourceDictionary>
  569. <ResourceDictionary.MergedDictionaries>
  570. <ResourceDictionary>
  571. <SolidColorBrush x:Key='brush' Color='{DynamicResource color}'/>
  572. </ResourceDictionary>
  573. </ResourceDictionary.MergedDictionaries>
  574. </ResourceDictionary>
  575. </UserControl.Resources>
  576. <Border Name='border' Background='{DynamicResource brush}'/>
  577. </UserControl>";
  578. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  579. var border = userControl.FindControl<Border>("border");
  580. DelayedBinding.ApplyBindings(border);
  581. var brush = (SolidColorBrush)border.Background;
  582. Assert.Equal(0u, brush.Color.ToUint32());
  583. brush.GetObservable(SolidColorBrush.ColorProperty).Subscribe(_ => { });
  584. using (UnitTestApplication.Start(TestServices.StyledWindow))
  585. {
  586. var window = new Window
  587. {
  588. Resources =
  589. {
  590. { "color", Colors.Red }
  591. },
  592. Content = userControl,
  593. };
  594. window.Show();
  595. Assert.Equal(Colors.Red, brush.Color);
  596. }
  597. }
  598. [Fact]
  599. public void Style_Resource_With_DynamicResource_Is_Updated_When_Added_To_Parent()
  600. {
  601. var xaml = @"
  602. <UserControl xmlns='https://github.com/avaloniaui'
  603. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  604. <UserControl.Styles>
  605. <Style>
  606. <Style.Resources>
  607. <SolidColorBrush x:Key='brush' Color='{DynamicResource color}'/>
  608. </Style.Resources>
  609. </Style>
  610. </UserControl.Styles>
  611. <Border Name='border' Background='{DynamicResource brush}'/>
  612. </UserControl>";
  613. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  614. var border = userControl.FindControl<Border>("border");
  615. DelayedBinding.ApplyBindings(border);
  616. var brush = (SolidColorBrush)border.Background;
  617. Assert.Equal(0u, brush.Color.ToUint32());
  618. using (UnitTestApplication.Start(TestServices.StyledWindow))
  619. {
  620. var window = new Window
  621. {
  622. Resources =
  623. {
  624. { "color", Colors.Red }
  625. },
  626. Content = userControl,
  627. };
  628. window.Show();
  629. Assert.Equal(Colors.Red, brush.Color);
  630. }
  631. }
  632. [Fact]
  633. public void Automatically_Converts_Color_To_SolidColorBrush()
  634. {
  635. var xaml = @"
  636. <UserControl xmlns='https://github.com/avaloniaui'
  637. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  638. <UserControl.Resources>
  639. <Color x:Key='color'>#ff506070</Color>
  640. </UserControl.Resources>
  641. <Border Name='border' Background='{DynamicResource color}'/>
  642. </UserControl>";
  643. var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  644. var border = userControl.FindControl<Border>("border");
  645. var brush = (ISolidColorBrush)border.Background;
  646. Assert.Equal(0xff506070, brush.Color.ToUint32());
  647. }
  648. private IDisposable StyledWindow(params (string, string)[] assets)
  649. {
  650. var services = TestServices.StyledWindow.With(
  651. assetLoader: new MockAssetLoader(assets),
  652. theme: () => new Styles
  653. {
  654. WindowStyle(),
  655. });
  656. return UnitTestApplication.Start(services);
  657. }
  658. private Style WindowStyle()
  659. {
  660. return new Style(x => x.OfType<Window>())
  661. {
  662. Setters =
  663. {
  664. new Setter(
  665. Window.TemplateProperty,
  666. new FuncControlTemplate<Window>((x, scope) =>
  667. new ContentPresenter
  668. {
  669. Name = "PART_ContentPresenter",
  670. [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
  671. }.RegisterInNameScope(scope)))
  672. }
  673. };
  674. }
  675. }
  676. }