CompiledBindingExtensionTests.cs 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Globalization;
  6. using System.Linq;
  7. using System.Reactive.Subjects;
  8. using System.Threading.Tasks;
  9. using Avalonia.Controls;
  10. using Avalonia.Controls.Presenters;
  11. using Avalonia.Controls.Templates;
  12. using Avalonia.Data;
  13. using Avalonia.Data.Converters;
  14. using Avalonia.Data.Core;
  15. using Avalonia.Input;
  16. using Avalonia.Markup.Data;
  17. using Avalonia.Markup.Xaml.MarkupExtensions;
  18. using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings;
  19. using Avalonia.Markup.Xaml.Templates;
  20. using Avalonia.Media;
  21. using Avalonia.Metadata;
  22. using Avalonia.UnitTests;
  23. using Xunit;
  24. namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
  25. {
  26. public class CompiledBindingExtensionTests
  27. {
  28. [Fact]
  29. public void ResolvesClrPropertyBasedOnDataContextType()
  30. {
  31. using (UnitTestApplication.Start(TestServices.StyledWindow))
  32. {
  33. var xaml = @"
  34. <Window xmlns='https://github.com/avaloniaui'
  35. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  36. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  37. x:DataType='local:TestDataContext'>
  38. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  39. </Window>";
  40. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  41. var textBlock = window.FindControl<TextBlock>("textBlock");
  42. var dataContext = new TestDataContext
  43. {
  44. StringProperty = "foobar"
  45. };
  46. window.DataContext = dataContext;
  47. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  48. }
  49. }
  50. [Fact]
  51. public void ResolvesClrPropertyBasedOnDataContextType_InterfaceInheritance()
  52. {
  53. using (UnitTestApplication.Start(TestServices.StyledWindow))
  54. {
  55. var xaml = @"
  56. <Window xmlns='https://github.com/avaloniaui'
  57. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  58. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  59. x:DataType='local:IHasPropertyDerived'>
  60. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  61. </Window>";
  62. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  63. var textBlock = window.FindControl<TextBlock>("textBlock");
  64. var dataContext = new TestDataContext
  65. {
  66. StringProperty = "foobar"
  67. };
  68. window.DataContext = dataContext;
  69. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  70. }
  71. }
  72. [Fact]
  73. public void ResolvesPathPassedByProperty()
  74. {
  75. using (UnitTestApplication.Start(TestServices.StyledWindow))
  76. {
  77. var xaml = @"
  78. <Window xmlns='https://github.com/avaloniaui'
  79. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  80. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  81. x:DataType='local:TestDataContext'>
  82. <TextBlock Text='{CompiledBinding Path=StringProperty}' Name='textBlock' />
  83. </Window>";
  84. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  85. var textBlock = window.FindControl<TextBlock>("textBlock");
  86. var dataContext = new TestDataContext
  87. {
  88. StringProperty = "foobar"
  89. };
  90. window.DataContext = dataContext;
  91. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  92. }
  93. }
  94. [Fact]
  95. public void ResolvesPathPassedByPropertyWithInnerItemTemplate()
  96. {
  97. using (UnitTestApplication.Start(TestServices.StyledWindow))
  98. {
  99. var xaml = @"
  100. <Window xmlns='https://github.com/avaloniaui'
  101. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  102. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  103. x:DataType='local:TestDataContext'>
  104. <ItemsControl Name='itemsControl' Items='{CompiledBinding Path=ListProperty}'>
  105. <ItemsControl.ItemTemplate>
  106. <DataTemplate>
  107. <TextBlock />
  108. </DataTemplate>
  109. </ItemsControl.ItemTemplate>
  110. </ItemsControl>
  111. </Window>";
  112. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  113. var textBlock = window.FindControl<ItemsControl>("itemsControl");
  114. var dataContext = new TestDataContext
  115. {
  116. ListProperty =
  117. {
  118. "Hello"
  119. }
  120. };
  121. window.DataContext = dataContext;
  122. Assert.Equal(dataContext.ListProperty, textBlock.Items);
  123. }
  124. }
  125. [Fact]
  126. public void ResolvesDataTypeFromBindingProperty()
  127. {
  128. using (UnitTestApplication.Start(TestServices.StyledWindow))
  129. {
  130. var xaml = @"
  131. <Window xmlns='https://github.com/avaloniaui'
  132. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  133. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  134. <TextBlock Text='{CompiledBinding StringProperty, DataType=local:TestDataContext}' Name='textBlock' />
  135. </Window>";
  136. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  137. var textBlock = window.FindControl<TextBlock>("textBlock");
  138. var dataContext = new TestDataContext
  139. {
  140. StringProperty = "foobar"
  141. };
  142. window.DataContext = dataContext;
  143. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  144. }
  145. }
  146. [Fact]
  147. public void ResolvesDataTypeFromBindingProperty_TypeExtension()
  148. {
  149. using (UnitTestApplication.Start(TestServices.StyledWindow))
  150. {
  151. var xaml = @"
  152. <Window xmlns='https://github.com/avaloniaui'
  153. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  154. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  155. <TextBlock Text='{CompiledBinding StringProperty, DataType={x:Type local:TestDataContext}}' Name='textBlock' />
  156. </Window>";
  157. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  158. var textBlock = window.FindControl<TextBlock>("textBlock");
  159. var dataContext = new TestDataContext
  160. {
  161. StringProperty = "foobar"
  162. };
  163. window.DataContext = dataContext;
  164. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  165. }
  166. }
  167. [Fact]
  168. public void ResolvesStreamTaskBindingCorrectly()
  169. {
  170. using (UnitTestApplication.Start(TestServices.StyledWindow))
  171. {
  172. var xaml = @"
  173. <Window xmlns='https://github.com/avaloniaui'
  174. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  175. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  176. x:DataType='local:TestDataContext'>
  177. <TextBlock Text='{CompiledBinding TaskProperty^}' Name='textBlock' />
  178. </Window>";
  179. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  180. var textBlock = window.FindControl<TextBlock>("textBlock");
  181. var dataContext = new TestDataContext
  182. {
  183. TaskProperty = Task.FromResult("foobar")
  184. };
  185. window.DataContext = dataContext;
  186. Assert.Equal(dataContext.TaskProperty.Result, textBlock.Text);
  187. }
  188. }
  189. [Fact]
  190. public void ResolvesStreamObservableBindingCorrectly()
  191. {
  192. using (UnitTestApplication.Start(TestServices.StyledWindow))
  193. {
  194. var xaml = @"
  195. <Window xmlns='https://github.com/avaloniaui'
  196. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  197. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  198. x:DataType='local:TestDataContext'>
  199. <TextBlock Text='{CompiledBinding ObservableProperty^}' Name='textBlock' />
  200. </Window>";
  201. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  202. var textBlock = window.FindControl<TextBlock>("textBlock");
  203. DelayedBinding.ApplyBindings(textBlock);
  204. var subject = new Subject<string>();
  205. var dataContext = new TestDataContext
  206. {
  207. ObservableProperty = subject
  208. };
  209. window.DataContext = dataContext;
  210. subject.OnNext("foobar");
  211. Assert.Equal("foobar", textBlock.Text);
  212. }
  213. }
  214. [Fact]
  215. public void ResolvesIndexerBindingCorrectly()
  216. {
  217. using (UnitTestApplication.Start(TestServices.StyledWindow))
  218. {
  219. var xaml = @"
  220. <Window xmlns='https://github.com/avaloniaui'
  221. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  222. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  223. x:DataType='local:TestDataContext'>
  224. <TextBlock Text='{CompiledBinding ListProperty[3]}' Name='textBlock' />
  225. </Window>";
  226. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  227. var textBlock = window.FindControl<TextBlock>("textBlock");
  228. var dataContext = new TestDataContext
  229. {
  230. ListProperty = { "A", "B", "C", "D", "E" }
  231. };
  232. window.DataContext = dataContext;
  233. Assert.Equal(dataContext.ListProperty[3], textBlock.Text);
  234. }
  235. }
  236. [Fact]
  237. public void ResolvesArrayIndexerBindingCorrectly()
  238. {
  239. using (UnitTestApplication.Start(TestServices.StyledWindow))
  240. {
  241. var xaml = @"
  242. <Window xmlns='https://github.com/avaloniaui'
  243. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  244. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  245. x:DataType='local:TestDataContext'>
  246. <TextBlock Text='{CompiledBinding ArrayProperty[3]}' Name='textBlock' />
  247. </Window>";
  248. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  249. var textBlock = window.FindControl<TextBlock>("textBlock");
  250. var dataContext = new TestDataContext
  251. {
  252. ArrayProperty = new[] { "A", "B", "C", "D", "E" }
  253. };
  254. window.DataContext = dataContext;
  255. Assert.Equal(dataContext.ArrayProperty[3], textBlock.Text);
  256. }
  257. }
  258. [Fact]
  259. public void ResolvesObservableIndexerBindingCorrectly()
  260. {
  261. using (UnitTestApplication.Start(TestServices.StyledWindow))
  262. {
  263. var xaml = @"
  264. <Window xmlns='https://github.com/avaloniaui'
  265. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  266. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  267. x:DataType='local:TestDataContext'>
  268. <TextBlock Text='{CompiledBinding ObservableCollectionProperty[3]}' Name='textBlock' />
  269. </Window>";
  270. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  271. var textBlock = window.FindControl<TextBlock>("textBlock");
  272. var dataContext = new TestDataContext
  273. {
  274. ObservableCollectionProperty = { "A", "B", "C", "D", "E" }
  275. };
  276. window.DataContext = dataContext;
  277. Assert.Equal(dataContext.ObservableCollectionProperty[3], textBlock.Text);
  278. dataContext.ObservableCollectionProperty[3] = "New Value";
  279. Assert.Equal(dataContext.ObservableCollectionProperty[3], textBlock.Text);
  280. }
  281. }
  282. [Fact]
  283. public void InfersCompiledBindingDataContextFromDataContextBinding()
  284. {
  285. using (UnitTestApplication.Start(TestServices.StyledWindow))
  286. {
  287. var xaml = @"
  288. <Window xmlns='https://github.com/avaloniaui'
  289. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  290. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  291. x:DataType='local:TestDataContext'>
  292. <TextBlock DataContext='{CompiledBinding StringProperty}' Text='{CompiledBinding}' Name='textBlock' />
  293. </Window>";
  294. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  295. var textBlock = window.FindControl<TextBlock>("textBlock");
  296. window.ApplyTemplate();
  297. window.Presenter.ApplyTemplate();
  298. var dataContext = new TestDataContext
  299. {
  300. StringProperty = "A"
  301. };
  302. window.DataContext = dataContext;
  303. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  304. }
  305. }
  306. [Fact]
  307. public void ResolvesNonIntegerIndexerBindingCorrectly()
  308. {
  309. using (UnitTestApplication.Start(TestServices.StyledWindow))
  310. {
  311. var xaml = @"
  312. <Window xmlns='https://github.com/avaloniaui'
  313. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  314. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  315. x:DataType='local:TestDataContext'>
  316. <TextBlock Text='{CompiledBinding NonIntegerIndexerProperty[Test]}' Name='textBlock' />
  317. </Window>";
  318. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  319. var textBlock = window.FindControl<TextBlock>("textBlock");
  320. var dataContext = new TestDataContext();
  321. dataContext.NonIntegerIndexerProperty["Test"] = "Initial Value";
  322. window.DataContext = dataContext;
  323. Assert.Equal(dataContext.NonIntegerIndexerProperty["Test"], textBlock.Text);
  324. dataContext.NonIntegerIndexerProperty["Test"] = "New Value";
  325. Assert.Equal(dataContext.NonIntegerIndexerProperty["Test"], textBlock.Text);
  326. }
  327. }
  328. [Fact]
  329. public void ResolvesNonIntegerIndexerBindingFromParentInterfaceCorrectly()
  330. {
  331. using (UnitTestApplication.Start(TestServices.StyledWindow))
  332. {
  333. var xaml = @"
  334. <Window xmlns='https://github.com/avaloniaui'
  335. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  336. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  337. x:DataType='local:TestDataContext'>
  338. <TextBlock Text='{CompiledBinding NonIntegerIndexerInterfaceProperty[Test]}' Name='textBlock' />
  339. </Window>";
  340. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  341. var textBlock = window.FindControl<TextBlock>("textBlock");
  342. var dataContext = new TestDataContext();
  343. dataContext.NonIntegerIndexerInterfaceProperty["Test"] = "Initial Value";
  344. window.DataContext = dataContext;
  345. Assert.Equal(dataContext.NonIntegerIndexerInterfaceProperty["Test"], textBlock.Text);
  346. dataContext.NonIntegerIndexerInterfaceProperty["Test"] = "New Value";
  347. Assert.Equal(dataContext.NonIntegerIndexerInterfaceProperty["Test"], textBlock.Text);
  348. }
  349. }
  350. [Fact]
  351. public void InfersDataTemplateTypeFromDataTypeProperty()
  352. {
  353. using (UnitTestApplication.Start(TestServices.StyledWindow))
  354. {
  355. var xaml = @"
  356. <Window xmlns='https://github.com/avaloniaui'
  357. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  358. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  359. x:DataType='local:TestDataContext'>
  360. <Window.DataTemplates>
  361. <DataTemplate DataType='{x:Type x:String}'>
  362. <TextBlock Text='{CompiledBinding}' Name='textBlock' />
  363. </DataTemplate>
  364. </Window.DataTemplates>
  365. <ContentControl Name='target' Content='{CompiledBinding StringProperty}' />
  366. </Window>";
  367. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  368. var target = window.FindControl<ContentControl>("target");
  369. var dataContext = new TestDataContext();
  370. dataContext.StringProperty = "Initial Value";
  371. window.DataContext = dataContext;
  372. window.ApplyTemplate();
  373. target.ApplyTemplate();
  374. ((ContentPresenter)target.Presenter).UpdateChild();
  375. Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
  376. }
  377. }
  378. [Fact]
  379. public void ThrowsOnUninferrableLooseDataTemplateNoDataTypeWithCompiledBindingPath()
  380. {
  381. using (UnitTestApplication.Start(TestServices.StyledWindow))
  382. {
  383. var xaml = @"
  384. <Window xmlns='https://github.com/avaloniaui'
  385. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  386. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  387. x:DataType='local:TestDataContext'>
  388. <Window.DataTemplates>
  389. <DataTemplate>
  390. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  391. </DataTemplate>
  392. </Window.DataTemplates>
  393. <ContentControl Name='target' Content='{CompiledBinding}' />
  394. </Window>";
  395. ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
  396. }
  397. }
  398. [Fact]
  399. public void ThrowsOnUninferrableDataTypeFromNonCompiledDataContextBindingWithCompiledBindingPath()
  400. {
  401. using (UnitTestApplication.Start(TestServices.StyledWindow))
  402. {
  403. var xaml = @"
  404. <Window xmlns='https://github.com/avaloniaui'
  405. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  406. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  407. x:DataType='local:TestDataContext'>
  408. <ContentControl Name='target' DataContext='{Binding}'>
  409. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  410. </ContentControl>
  411. </Window>";
  412. ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
  413. }
  414. }
  415. [Fact]
  416. public void InfersDataTemplateTypeFromParentCollectionItemsType()
  417. {
  418. using (UnitTestApplication.Start(TestServices.StyledWindow))
  419. {
  420. var xaml = @"
  421. <Window xmlns='https://github.com/avaloniaui'
  422. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  423. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  424. x:DataType='local:TestDataContext'>
  425. <ItemsControl Items='{CompiledBinding ListProperty}' Name='target'>
  426. <ItemsControl.ItemTemplate>
  427. <DataTemplate>
  428. <TextBlock Text='{CompiledBinding}' Name='textBlock' />
  429. </DataTemplate>
  430. </ItemsControl.ItemTemplate>
  431. </ItemsControl>
  432. </Window>";
  433. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  434. var target = window.FindControl<ItemsControl>("target");
  435. var dataContext = new TestDataContext();
  436. dataContext.ListProperty.Add("Test");
  437. window.DataContext = dataContext;
  438. window.ApplyTemplate();
  439. target.ApplyTemplate();
  440. target.Presenter.ApplyTemplate();
  441. Assert.Equal(dataContext.ListProperty[0], (string)((ContentPresenter)target.Presenter.Panel.Children[0]).Content);
  442. }
  443. }
  444. [Fact]
  445. public void ThrowsOnUninferrableDataTemplateInItemsControlWithoutItemsBinding()
  446. {
  447. using (UnitTestApplication.Start(TestServices.StyledWindow))
  448. {
  449. var xaml = @"
  450. <Window xmlns='https://github.com/avaloniaui'
  451. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  452. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  453. x:DataType='local:TestDataContext'>
  454. <ItemsControl Name='target'>
  455. <ItemsControl.DataTemplates>
  456. <DataTemplate>
  457. <TextBlock Text='{CompiledBinding Property}' Name='textBlock' />
  458. </DataTemplate>
  459. </ItemsControl.DataTemplates>
  460. </ItemsControl>
  461. </Window>";
  462. ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
  463. }
  464. }
  465. [Fact]
  466. public void IgnoresDataTemplateTypeFromDataTypePropertyIfXDataTypeDefined()
  467. {
  468. using (UnitTestApplication.Start(TestServices.StyledWindow))
  469. {
  470. var xaml = @"
  471. <Window xmlns='https://github.com/avaloniaui'
  472. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  473. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  474. <Window.DataTemplates>
  475. <DataTemplate DataType='local:TestDataContextBaseClass' x:DataType='local:TestDataContext'>
  476. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  477. </DataTemplate>
  478. </Window.DataTemplates>
  479. <ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
  480. </Window>";
  481. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  482. var target = window.FindControl<ContentControl>("target");
  483. var dataContext = new TestDataContext();
  484. dataContext.StringProperty = "Initial Value";
  485. window.DataContext = dataContext;
  486. window.ApplyTemplate();
  487. target.ApplyTemplate();
  488. ((ContentPresenter)target.Presenter).UpdateChild();
  489. Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
  490. }
  491. }
  492. [Fact]
  493. public void InfersCustomDataTemplateBasedOnAttribute()
  494. {
  495. using (UnitTestApplication.Start(TestServices.StyledWindow))
  496. {
  497. var xaml = @"
  498. <Window xmlns='https://github.com/avaloniaui'
  499. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  500. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  501. <Window.DataTemplates>
  502. <local:CustomDataTemplate FancyDataType='local:TestDataContext'>
  503. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  504. </local:CustomDataTemplate>
  505. </Window.DataTemplates>
  506. <ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
  507. </Window>";
  508. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  509. var target = window.FindControl<ContentControl>("target");
  510. var dataContext = new TestDataContext();
  511. dataContext.StringProperty = "Initial Value";
  512. window.DataContext = dataContext;
  513. window.ApplyTemplate();
  514. target.ApplyTemplate();
  515. ((ContentPresenter)target.Presenter).UpdateChild();
  516. Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
  517. }
  518. }
  519. [Fact]
  520. public void InfersCustomDataTemplateBasedOnAttributeFromBaseClass()
  521. {
  522. using (UnitTestApplication.Start(TestServices.StyledWindow))
  523. {
  524. var xaml = @"
  525. <Window xmlns='https://github.com/avaloniaui'
  526. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  527. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  528. <Window.DataTemplates>
  529. <local:CustomDataTemplateInherit FancyDataType='local:TestDataContext'>
  530. <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
  531. </local:CustomDataTemplateInherit>
  532. </Window.DataTemplates>
  533. <ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
  534. </Window>";
  535. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  536. var target = window.FindControl<ContentControl>("target");
  537. var dataContext = new TestDataContext();
  538. dataContext.StringProperty = "Initial Value";
  539. window.DataContext = dataContext;
  540. window.ApplyTemplate();
  541. target.ApplyTemplate();
  542. ((ContentPresenter)target.Presenter).UpdateChild();
  543. Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
  544. }
  545. }
  546. [Fact]
  547. public void ResolvesElementNameBinding()
  548. {
  549. using (UnitTestApplication.Start(TestServices.StyledWindow))
  550. {
  551. var xaml = @"
  552. <Window xmlns='https://github.com/avaloniaui'
  553. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  554. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  555. x:DataType='local:TestDataContext'>
  556. <StackPanel>
  557. <TextBlock Text='{CompiledBinding StringProperty}' x:Name='text' />
  558. <TextBlock Text='{CompiledBinding #text.Text}' x:Name='text2' />
  559. </StackPanel>
  560. </Window>";
  561. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  562. var textBlock = window.FindControl<TextBlock>("text2");
  563. var dataContext = new TestDataContext
  564. {
  565. StringProperty = "foobar"
  566. };
  567. window.DataContext = dataContext;
  568. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  569. }
  570. }
  571. [Fact]
  572. public void ResolvesElementNameBindingFromLongForm()
  573. {
  574. using (UnitTestApplication.Start(TestServices.StyledWindow))
  575. {
  576. var xaml = @"
  577. <Window xmlns='https://github.com/avaloniaui'
  578. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  579. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  580. x:DataType='local:TestDataContext'>
  581. <StackPanel>
  582. <TextBlock Text='{CompiledBinding StringProperty}' x:Name='text' />
  583. <TextBlock Text='{CompiledBinding Text, ElementName=text}' x:Name='text2' />
  584. </StackPanel>
  585. </Window>";
  586. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  587. var textBlock = window.FindControl<TextBlock>("text2");
  588. var dataContext = new TestDataContext
  589. {
  590. StringProperty = "foobar"
  591. };
  592. window.DataContext = dataContext;
  593. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  594. }
  595. }
  596. [Fact]
  597. public void ResolvesRelativeSourceBindingLongForm()
  598. {
  599. using (UnitTestApplication.Start(TestServices.StyledWindow))
  600. {
  601. var xaml = @"
  602. <Window xmlns='https://github.com/avaloniaui'
  603. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  604. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  605. x:DataType='local:TestDataContext'
  606. Title='test'>
  607. <TextBlock Text='{CompiledBinding Title, RelativeSource={RelativeSource AncestorType=Window}}' x:Name='text'/>
  608. </Window>";
  609. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  610. var target = window.FindControl<TextBlock>("text");
  611. window.ApplyTemplate();
  612. window.Presenter.ApplyTemplate();
  613. target.ApplyTemplate();
  614. Assert.Equal("test", target.Text);
  615. }
  616. }
  617. [Fact]
  618. public void ResolvesRelativeSourceBindingFromTemplate()
  619. {
  620. using (UnitTestApplication.Start(TestServices.StyledWindow))
  621. {
  622. var xaml = @"
  623. <ContentControl xmlns='https://github.com/avaloniaui'
  624. Content='Hello'>
  625. <ContentControl.Styles>
  626. <Style Selector='ContentControl'>
  627. <Setter Property='Template'>
  628. <ControlTemplate>
  629. <ContentPresenter Content='{CompiledBinding Content, RelativeSource={RelativeSource TemplatedParent}}' />
  630. </ControlTemplate>
  631. </Setter>
  632. </Style>
  633. </ContentControl.Styles>
  634. </ContentControl>";
  635. var contentControl = AvaloniaRuntimeXamlLoader.Parse<ContentControl>(xaml);
  636. contentControl.Measure(new Size(10, 10));
  637. var result = contentControl.GetTemplateChildren().OfType<ContentPresenter>().First();
  638. Assert.Equal("Hello", result.Content);
  639. }
  640. }
  641. [Fact]
  642. public void ResolvesRelativeSourceBindingFromStyleSelector()
  643. {
  644. using (UnitTestApplication.Start(TestServices.StyledWindow))
  645. {
  646. var xaml = @"
  647. <TextBox xmlns='https://github.com/avaloniaui'
  648. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  649. InnerLeftContent='Hello'>
  650. <TextBox.Styles>
  651. <Style Selector='TextBox'>
  652. <Setter Property='Template'>
  653. <ControlTemplate>
  654. <StackPanel>
  655. <ContentPresenter x:Name='Content' />
  656. <TextPresenter x:Name='PART_TextPresenter' />
  657. </StackPanel>
  658. </ControlTemplate>
  659. </Setter>
  660. <Style Selector='^ /template/ ContentPresenter#Content'>
  661. <Setter Property='Content' Value='{CompiledBinding InnerLeftContent, RelativeSource={RelativeSource TemplatedParent}}' />
  662. </Style>
  663. </Style>
  664. </TextBox.Styles>
  665. </TextBox>";
  666. var textBox = AvaloniaRuntimeXamlLoader.Parse<TextBox>(xaml);
  667. textBox.Measure(new Size(10, 10));
  668. var result = textBox.GetTemplateChildren().OfType<ContentPresenter>().First();
  669. Assert.Equal(textBox.InnerLeftContent, result.Content);
  670. }
  671. }
  672. [Fact]
  673. public void ResolvesElementNameInTemplate()
  674. {
  675. using (UnitTestApplication.Start(TestServices.StyledWindow))
  676. {
  677. var xaml = @"
  678. <ContentControl xmlns='https://github.com/avaloniaui'
  679. Content='Hello'>
  680. <ContentControl.Styles>
  681. <Style Selector='ContentControl'>
  682. <Setter Property='Template'>
  683. <ControlTemplate>
  684. <Panel>
  685. <TextBox Name='InnerTextBox' Text='Hello' />
  686. <ContentPresenter Content='{CompiledBinding Text, ElementName=InnerTextBox}' />
  687. </Panel>
  688. </ControlTemplate>
  689. </Setter>
  690. </Style>
  691. </ContentControl.Styles>
  692. </ContentControl>";
  693. var contentControl = AvaloniaRuntimeXamlLoader.Parse<ContentControl>(xaml);
  694. contentControl.Measure(new Size(10, 10));
  695. var result = contentControl.GetTemplateChildren().OfType<ContentPresenter>().First();
  696. Assert.Equal("Hello", result.Content);
  697. }
  698. }
  699. [Fact]
  700. public void Binds_To_Source()
  701. {
  702. using (UnitTestApplication.Start(TestServices.StyledWindow))
  703. {
  704. var xaml = @"
  705. <Window xmlns='https://github.com/avaloniaui'
  706. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  707. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  708. x:DataType='local:TestDataContext'
  709. Title='test'>
  710. <TextBlock Text='{CompiledBinding Length, Source=Test}' x:Name='text'/>
  711. </Window>";
  712. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  713. var target = window.FindControl<TextBlock>("text");
  714. window.ApplyTemplate();
  715. window.Presenter.ApplyTemplate();
  716. target.ApplyTemplate();
  717. Assert.Equal("Test".Length.ToString(), target.Text);
  718. }
  719. }
  720. [Fact]
  721. public void Binds_To_Source_StaticResource()
  722. {
  723. using (UnitTestApplication.Start(TestServices.StyledWindow))
  724. {
  725. var xaml = @"
  726. <Window xmlns='https://github.com/avaloniaui'
  727. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  728. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  729. x:CompileBindings='True'>
  730. <Window.Resources>
  731. <local:TestDataContext x:Key='dataKey' StringProperty='foobar'/>
  732. </Window.Resources>
  733. <TextBlock Name='textBlock' Text='{Binding StringProperty, Source={StaticResource dataKey}}'/>
  734. </Window>";
  735. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  736. var textBlock = window.FindControl<TextBlock>("textBlock");
  737. Assert.Equal("foobar", textBlock.Text);
  738. }
  739. }
  740. [Fact]
  741. public void Binds_To_Source_StaticResource1()
  742. {
  743. using (UnitTestApplication.Start(TestServices.StyledWindow))
  744. {
  745. var xaml = @"
  746. <Window xmlns='https://github.com/avaloniaui'
  747. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  748. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  749. x:CompileBindings='True'>
  750. <Window.Resources>
  751. <local:TestDataContext x:Key='dataKey' StringProperty='foobar'/>
  752. <x:String x:Key='otherObjectKey'>test</x:String>
  753. </Window.Resources>
  754. <TextBlock Name='textBlock' Text='{Binding StringProperty, Source={StaticResource dataKey}}'/>
  755. </Window>";
  756. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  757. var textBlock = window.FindControl<TextBlock>("textBlock");
  758. Assert.Equal("foobar", textBlock.Text);
  759. }
  760. }
  761. [Fact]
  762. public void Binds_To_Source_StaticResource_In_ResourceDictionary()
  763. {
  764. using (UnitTestApplication.Start(TestServices.StyledWindow))
  765. {
  766. var xaml = @"
  767. <Window xmlns='https://github.com/avaloniaui'
  768. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  769. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  770. x:DataType='local:TestDataContext' x:CompileBindings='True'>
  771. <Window.Resources>
  772. <ResourceDictionary>
  773. <local:TestDataContext x:Key='dataKey' StringProperty='foobar'/>
  774. </ResourceDictionary>
  775. </Window.Resources>
  776. <TextBlock Name='textBlock' Text='{Binding StringProperty, Source={StaticResource dataKey}}'/>
  777. </Window>";
  778. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  779. var textBlock = window.FindControl<TextBlock>("textBlock");
  780. Assert.Equal("foobar", textBlock.Text);
  781. }
  782. }
  783. [Fact]
  784. public void Binds_To_Source_StaticResource_In_ResourceDictionary1()
  785. {
  786. using (UnitTestApplication.Start(TestServices.StyledWindow))
  787. {
  788. var xaml = @"
  789. <Window xmlns='https://github.com/avaloniaui'
  790. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  791. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  792. x:DataType='local:TestDataContext' x:CompileBindings='True'>
  793. <Window.Resources>
  794. <ResourceDictionary>
  795. <local:TestDataContext x:Key='dataKey' StringProperty='foobar'/>
  796. <x:String x:Key='otherObjectKey'>test</x:String>
  797. </ResourceDictionary>
  798. </Window.Resources>
  799. <TextBlock Name='textBlock' Text='{Binding StringProperty, Source={StaticResource dataKey}}'/>
  800. </Window>";
  801. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  802. var textBlock = window.FindControl<TextBlock>("textBlock");
  803. Assert.Equal("foobar", textBlock.Text);
  804. }
  805. }
  806. [Fact]
  807. public void Binds_To_Source_xStatic()
  808. {
  809. using (UnitTestApplication.Start(TestServices.StyledWindow))
  810. {
  811. var xaml = @"
  812. <Window xmlns='https://github.com/avaloniaui'
  813. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  814. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  815. x:CompileBindings='True'>
  816. <ContentControl Name='contentControl' Content='{Binding Color, Source={x:Static Brushes.Red}}'/>
  817. </Window>";
  818. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  819. var contentControl = window.FindControl<ContentControl>("contentControl");
  820. Assert.Equal(Brushes.Red.Color, contentControl.Content);
  821. }
  822. }
  823. [Fact]
  824. public void CompilesBindingWhenRequested()
  825. {
  826. using (UnitTestApplication.Start(TestServices.StyledWindow))
  827. {
  828. var xaml = @"
  829. <Window xmlns='https://github.com/avaloniaui'
  830. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  831. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  832. x:DataType='local:TestDataContext'
  833. x:CompileBindings='true'>
  834. <TextBlock Text='{Binding StringProperty}' Name='textBlock' />
  835. </Window>";
  836. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  837. var textBlock = window.FindControl<TextBlock>("textBlock");
  838. var dataContext = new TestDataContext
  839. {
  840. StringProperty = "foobar"
  841. };
  842. window.DataContext = dataContext;
  843. Assert.Equal(dataContext.StringProperty, textBlock.Text);
  844. }
  845. }
  846. [Fact]
  847. public void ThrowsOnInvalidBindingPathOnCompiledBindingEnabledViaDirective()
  848. {
  849. using (UnitTestApplication.Start(TestServices.StyledWindow))
  850. {
  851. var xaml = @"
  852. <Window xmlns='https://github.com/avaloniaui'
  853. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  854. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  855. x:DataType='local:TestDataContext'
  856. x:CompileBindings='true'>
  857. <TextBlock Text='{Binding InvalidPath}' Name='textBlock' />
  858. </Window>";
  859. ThrowsXamlParseException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
  860. }
  861. }
  862. [Fact]
  863. public void SupportParentInPath()
  864. {
  865. using (UnitTestApplication.Start(TestServices.StyledWindow))
  866. {
  867. var xaml = @"
  868. <Window xmlns='https://github.com/avaloniaui'
  869. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  870. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  871. Title='foo'>
  872. <ContentControl Content='{CompiledBinding $parent.Title}' Name='contentControl' />
  873. </Window>";
  874. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  875. var contentControl = window.FindControl<ContentControl>("contentControl");
  876. Assert.Equal("foo", contentControl.Content);
  877. }
  878. }
  879. [Fact]
  880. public void SupportConverterWithParameter()
  881. {
  882. using (UnitTestApplication.Start(TestServices.StyledWindow))
  883. {
  884. var xaml = @"
  885. <Window xmlns='https://github.com/avaloniaui'
  886. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  887. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  888. x:DataType='local:TestDataContext' x:CompileBindings='True'>
  889. <TextBlock Name='textBlock' Text='{Binding StringProperty, Converter={x:Static local:AppendConverter.Instance}, ConverterParameter=Bar}'/>
  890. </Window>";
  891. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  892. var textBlock = window.FindControl<TextBlock>("textBlock");
  893. window.DataContext = new TestDataContext() { StringProperty = "Foo" };
  894. Assert.Equal("Foo+Bar", textBlock.Text);
  895. }
  896. }
  897. [Fact]
  898. public void ThrowsOnInvalidCompileBindingsDirective()
  899. {
  900. using (UnitTestApplication.Start(TestServices.StyledWindow))
  901. {
  902. var xaml = @"
  903. <Window xmlns='https://github.com/avaloniaui'
  904. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  905. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  906. x:DataType='local:TestDataContext'
  907. x:CompileBindings='notabool'>
  908. </Window>";
  909. ThrowsXamlParseException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
  910. }
  911. }
  912. [Fact]
  913. public void SupportCastToTypeInExpression()
  914. {
  915. using (UnitTestApplication.Start(TestServices.StyledWindow))
  916. {
  917. var xaml = @"
  918. <Window xmlns='https://github.com/avaloniaui'
  919. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  920. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  921. x:DataType='local:TestDataContext'>
  922. <ContentControl Content='{CompiledBinding $parent.((local:TestDataContext)DataContext)}' Name='contentControl' />
  923. </Window>";
  924. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  925. var contentControl = window.FindControl<ContentControl>("contentControl");
  926. var dataContext = new TestDataContext();
  927. window.DataContext = dataContext;
  928. Assert.Equal(dataContext, contentControl.Content);
  929. }
  930. }
  931. [Fact]
  932. public void SupportCastToTypeInExpression_DifferentTypeEvaluatesToNull()
  933. {
  934. using (UnitTestApplication.Start(TestServices.StyledWindow))
  935. {
  936. var xaml = @"
  937. <Window xmlns='https://github.com/avaloniaui'
  938. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  939. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  940. x:DataType='local:TestDataContext'>
  941. <ContentControl Content='{CompiledBinding $parent.((local:TestDataContext)DataContext)}' Name='contentControl' />
  942. </Window>";
  943. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  944. var contentControl = window.FindControl<ContentControl>("contentControl");
  945. var dataContext = "foo";
  946. window.DataContext = dataContext;
  947. Assert.Equal(null, contentControl.Content);
  948. }
  949. }
  950. [Fact]
  951. public void SupportCastToTypeInExpressionWithProperty()
  952. {
  953. using (UnitTestApplication.Start(TestServices.StyledWindow))
  954. {
  955. var xaml = @"
  956. <Window xmlns='https://github.com/avaloniaui'
  957. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  958. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  959. x:DataType='local:TestDataContext'>
  960. <ContentControl Content='{CompiledBinding $parent.((local:TestDataContext)DataContext).StringProperty}' Name='contentControl' />
  961. </Window>";
  962. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  963. var contentControl = window.FindControl<ContentControl>("contentControl");
  964. var dataContext = new TestDataContext
  965. {
  966. StringProperty = "foobar"
  967. };
  968. window.DataContext = dataContext;
  969. Assert.Equal(dataContext.StringProperty, contentControl.Content);
  970. }
  971. }
  972. [Fact]
  973. public void SupportCastToTypeInExpressionWithProperty1()
  974. {
  975. using (UnitTestApplication.Start(TestServices.StyledWindow))
  976. {
  977. var xaml = @"
  978. <Window xmlns='https://github.com/avaloniaui'
  979. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  980. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  981. x:DataType='local:TestDataContext'>
  982. <ContentControl Content='{CompiledBinding $parent.DataContext(local:TestDataContext).StringProperty}' Name='contentControl' />
  983. </Window>";
  984. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  985. var contentControl = window.FindControl<ContentControl>("contentControl");
  986. var dataContext = new TestDataContext
  987. {
  988. StringProperty = "foobar"
  989. };
  990. window.DataContext = dataContext;
  991. Assert.Equal(dataContext.StringProperty, contentControl.Content);
  992. }
  993. }
  994. [Fact]
  995. public void SupportCastToTypeInExpressionWithPropertyIndexer()
  996. {
  997. using (UnitTestApplication.Start(TestServices.StyledWindow))
  998. {
  999. var xaml = @"
  1000. <Window xmlns='https://github.com/avaloniaui'
  1001. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1002. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  1003. x:DataType='local:TestDataContext'>
  1004. <ContentControl Content='{CompiledBinding ((local:TestData)ObjectsArrayProperty[0]).StringProperty}' Name='contentControl' />
  1005. </Window>";
  1006. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1007. var contentControl = window.FindControl<ContentControl>("contentControl");
  1008. var data = new TestData()
  1009. {
  1010. StringProperty = "Foo"
  1011. };
  1012. var dataContext = new TestDataContext
  1013. {
  1014. ObjectsArrayProperty = new object[] { data }
  1015. };
  1016. window.DataContext = dataContext;
  1017. Assert.Equal(data.StringProperty, contentControl.Content);
  1018. }
  1019. }
  1020. [Fact]
  1021. public void SupportCastToTypeInExpressionWithProperty_DifferentTypeEvaluatesToNull()
  1022. {
  1023. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1024. {
  1025. var xaml = @"
  1026. <Window xmlns='https://github.com/avaloniaui'
  1027. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1028. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'
  1029. x:DataType='local:TestDataContext'>
  1030. <ContentControl Content='{CompiledBinding $parent.((local:TestDataContext)DataContext).StringProperty}' Name='contentControl' />
  1031. </Window>";
  1032. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1033. var contentControl = window.FindControl<ContentControl>("contentControl");
  1034. var dataContext = new TestDataContext
  1035. {
  1036. StringProperty = "foobar"
  1037. };
  1038. window.DataContext = dataContext;
  1039. Assert.Equal(dataContext.StringProperty, contentControl.Content);
  1040. window.DataContext = "foo";
  1041. Assert.Equal(null, contentControl.Content);
  1042. }
  1043. }
  1044. [Fact]
  1045. public void SupportsEmptyPath()
  1046. {
  1047. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1048. {
  1049. var xaml = @"
  1050. <Window xmlns='https://github.com/avaloniaui'
  1051. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1052. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1053. x:DataType='local:TestDataContext'>
  1054. <TextBlock Text='{CompiledBinding}' Name='textBlock' />
  1055. </Window>";
  1056. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1057. var textBlock = window.FindControl<TextBlock>("textBlock");
  1058. var dataContext = new TestDataContext
  1059. {
  1060. StringProperty = "foobar"
  1061. };
  1062. window.DataContext = dataContext;
  1063. Assert.Equal(typeof(TestDataContext).FullName, textBlock.Text);
  1064. }
  1065. }
  1066. [Fact]
  1067. public void SupportsEmptyPathWithStringFormat()
  1068. {
  1069. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1070. {
  1071. var xaml = @"
  1072. <Window xmlns='https://github.com/avaloniaui'
  1073. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1074. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1075. x:DataType='local:TestDataContext'>
  1076. <TextBlock Text='{CompiledBinding StringFormat=bar-\{0\}}' Name='textBlock' />
  1077. </Window>";
  1078. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1079. var textBlock = window.FindControl<TextBlock>("textBlock");
  1080. var dataContext = new TestDataContext
  1081. {
  1082. StringProperty = "foobar"
  1083. };
  1084. window.DataContext = dataContext;
  1085. Assert.Equal("bar-" + typeof(TestDataContext).FullName, textBlock.Text);
  1086. }
  1087. }
  1088. [Fact]
  1089. public void SupportsDotPath()
  1090. {
  1091. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1092. {
  1093. var xaml = @"
  1094. <Window xmlns='https://github.com/avaloniaui'
  1095. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1096. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1097. x:DataType='local:TestDataContext'>
  1098. <TextBlock Text='{CompiledBinding .}' Name='textBlock' />
  1099. </Window>";
  1100. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1101. var textBlock = window.FindControl<TextBlock>("textBlock");
  1102. var dataContext = new TestDataContext
  1103. {
  1104. StringProperty = "foobar"
  1105. };
  1106. window.DataContext = dataContext;
  1107. Assert.Equal(typeof(TestDataContext).FullName, textBlock.Text);
  1108. }
  1109. }
  1110. [Fact]
  1111. public void SupportsExplicitDotPathWithStringFormat()
  1112. {
  1113. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1114. {
  1115. var xaml = @"
  1116. <Window xmlns='https://github.com/avaloniaui'
  1117. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1118. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1119. x:DataType='local:TestDataContext'>
  1120. <TextBlock Text='{CompiledBinding Path=., StringFormat=bar-\{0\}}' Name='textBlock' />
  1121. </Window>";
  1122. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1123. var textBlock = window.FindControl<TextBlock>("textBlock");
  1124. var dataContext = new TestDataContext
  1125. {
  1126. StringProperty = "foobar"
  1127. };
  1128. window.DataContext = dataContext;
  1129. Assert.Equal("bar-" + typeof(TestDataContext).FullName, textBlock.Text);
  1130. }
  1131. }
  1132. [Fact]
  1133. public void SupportCastToTypeInExpressionWithProperty_ExplicitPropertyCast()
  1134. {
  1135. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1136. {
  1137. var xaml = @"
  1138. <Window xmlns='https://github.com/avaloniaui'
  1139. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1140. xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'>
  1141. <ContentControl Content='{CompiledBinding $parent.((local:IHasExplicitProperty)DataContext).ExplicitProperty}' Name='contentControl' />
  1142. </Window>";
  1143. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1144. var contentControl = window.GetControl<ContentControl>("contentControl");
  1145. var dataContext = new TestDataContext();
  1146. window.DataContext = dataContext;
  1147. Assert.Equal(((IHasExplicitProperty)dataContext).ExplicitProperty, contentControl.Content);
  1148. }
  1149. }
  1150. [Fact]
  1151. public void Binds_To_Self_Without_DataType()
  1152. {
  1153. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1154. {
  1155. var xaml = @"
  1156. <Window xmlns='https://github.com/avaloniaui'
  1157. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1158. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
  1159. <TextBlock Name='textBlock' Text='{CompiledBinding $self.Name}' />
  1160. </Window>";
  1161. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1162. var textBlock = window.FindControl<TextBlock>("textBlock");
  1163. window.ApplyTemplate();
  1164. window.Presenter.ApplyTemplate();
  1165. Assert.Equal(textBlock.Name, textBlock.Text);
  1166. }
  1167. }
  1168. [Fact]
  1169. public void Binds_To_Self_In_Style()
  1170. {
  1171. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1172. {
  1173. var xaml = @"
  1174. <Window xmlns='https://github.com/avaloniaui'
  1175. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  1176. <Window.Styles>
  1177. <Style Selector='Button'>
  1178. <Setter Property='IsVisible' Value='{CompiledBinding $self.IsEnabled}' />
  1179. </Style>
  1180. </Window.Styles>
  1181. <Button Name='button' />
  1182. </Window>";
  1183. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1184. var button = window.FindControl<Button>("button");
  1185. window.ApplyTemplate();
  1186. window.Presenter.ApplyTemplate();
  1187. Assert.True(button.IsVisible);
  1188. button.IsEnabled = false;
  1189. Assert.False(button.IsVisible);
  1190. }
  1191. }
  1192. [Fact]
  1193. public void SupportsMethodBindingAsDelegate()
  1194. {
  1195. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1196. {
  1197. var xaml = @"
  1198. <Window xmlns='https://github.com/avaloniaui'
  1199. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1200. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1201. x:DataType='local:MethodDataContext'>
  1202. <StackPanel>
  1203. <ContentControl Content='{CompiledBinding Action}' Name='action' />
  1204. <ContentControl Content='{CompiledBinding Func}' Name='func' />
  1205. <ContentControl Content='{CompiledBinding Action16}' Name='action16' />
  1206. <ContentControl Content='{CompiledBinding Func16}' Name='func16' />
  1207. <ContentControl Content='{CompiledBinding CustomDelegateTypeVoid}' Name='customvoid' />
  1208. <ContentControl Content='{CompiledBinding CustomDelegateTypeInt}' Name='customint' />
  1209. </StackPanel>
  1210. </Window>";
  1211. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1212. window.DataContext = new MethodDataContext();
  1213. Assert.IsAssignableFrom(typeof(Action), window.FindControl<ContentControl>("action").Content);
  1214. Assert.IsAssignableFrom(typeof(Func<int>), window.FindControl<ContentControl>("func").Content);
  1215. Assert.IsAssignableFrom(typeof(Action<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>), window.FindControl<ContentControl>("action16").Content);
  1216. Assert.IsAssignableFrom(typeof(Func<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>), window.FindControl<ContentControl>("func16").Content);
  1217. Assert.True(typeof(Delegate).IsAssignableFrom(window.FindControl<ContentControl>("customvoid").Content.GetType()));
  1218. Assert.True(typeof(Delegate).IsAssignableFrom(window.FindControl<ContentControl>("customint").Content.GetType()));
  1219. }
  1220. }
  1221. [Fact]
  1222. public void Binding_Method_To_Command_Works()
  1223. {
  1224. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1225. {
  1226. var xaml = @"
  1227. <Window xmlns='https://github.com/avaloniaui'
  1228. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1229. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1230. x:DataType='local:MethodAsCommandDataContext'>
  1231. <Button Name='button' Command='{CompiledBinding Method}'/>
  1232. </Window>";
  1233. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1234. var button = window.FindControl<Button>("button");
  1235. var vm = new MethodAsCommandDataContext();
  1236. button.DataContext = vm;
  1237. window.ApplyTemplate();
  1238. Assert.NotNull(button.Command);
  1239. PerformClick(button);
  1240. Assert.Equal("Called", vm.Value);
  1241. }
  1242. }
  1243. [Fact]
  1244. public void Binding_Method_With_Parameter_To_Command_Works()
  1245. {
  1246. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1247. {
  1248. var xaml = @"
  1249. <Window xmlns='https://github.com/avaloniaui'
  1250. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1251. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1252. x:DataType='local:MethodAsCommandDataContext'>
  1253. <Button Name='button' Command='{CompiledBinding Method1}' CommandParameter='5'/>
  1254. </Window>";
  1255. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1256. var button = window.FindControl<Button>("button");
  1257. var vm = new MethodAsCommandDataContext();
  1258. button.DataContext = vm;
  1259. window.ApplyTemplate();
  1260. Assert.NotNull(button.Command);
  1261. PerformClick(button);
  1262. Assert.Equal("Called 5", vm.Value);
  1263. }
  1264. }
  1265. [Fact]
  1266. public void Binding_Method_To_TextBlock_Text_Works()
  1267. {
  1268. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1269. {
  1270. var xaml = @"
  1271. <Window xmlns='https://github.com/avaloniaui'
  1272. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1273. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1274. x:DataType='local:MethodAsCommandDataContext'>
  1275. <TextBlock Name='textBlock' Text='{CompiledBinding Method}'/>
  1276. </Window>";
  1277. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1278. var textBlock = window.FindControl<TextBlock>("textBlock");
  1279. var vm = new MethodAsCommandDataContext();
  1280. textBlock.DataContext = vm;
  1281. window.ApplyTemplate();
  1282. Assert.NotNull(textBlock.Text);
  1283. }
  1284. }
  1285. [Theory]
  1286. [InlineData(null, "Not called")]
  1287. [InlineData("A", "Do A")]
  1288. public void Binding_Method_With_Parameter_To_Command_CanExecute(object commandParameter, string result)
  1289. {
  1290. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1291. {
  1292. var xaml = @"
  1293. <Window xmlns='https://github.com/avaloniaui'
  1294. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1295. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1296. x:DataType='local:MethodAsCommandDataContext'>
  1297. <Button Name='button' Command='{CompiledBinding Do}' CommandParameter='{CompiledBinding Parameter, Mode=OneTime}'/>
  1298. </Window>";
  1299. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1300. var button = window.FindControl<Button>("button");
  1301. var vm = new MethodAsCommandDataContext()
  1302. {
  1303. Parameter = commandParameter
  1304. };
  1305. button.DataContext = vm;
  1306. window.ApplyTemplate();
  1307. Assert.NotNull(button.Command);
  1308. PerformClick(button);
  1309. Assert.Equal(vm.Value, result);
  1310. }
  1311. }
  1312. [Fact]
  1313. public void Binding_Method_With_Parameter_To_Command_CanExecute_DependsOn()
  1314. {
  1315. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1316. {
  1317. var xaml = @"
  1318. <Window xmlns='https://github.com/avaloniaui'
  1319. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1320. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1321. x:DataType='local:MethodAsCommandDataContext'>
  1322. <Button Name='button' Command='{CompiledBinding Do}' CommandParameter='{CompiledBinding Parameter, Mode=OneWay}'/>
  1323. </Window>";
  1324. var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
  1325. var button = window.FindControl<Button>("button");
  1326. var vm = new MethodAsCommandDataContext()
  1327. {
  1328. Parameter = null,
  1329. };
  1330. button.DataContext = vm;
  1331. window.ApplyTemplate();
  1332. Assert.NotNull(button.Command);
  1333. Assert.Equal(button.IsEffectivelyEnabled, false);
  1334. vm.Parameter = true;
  1335. Threading.Dispatcher.UIThread.RunJobs();
  1336. Assert.Equal(button.IsEffectivelyEnabled, true);
  1337. }
  1338. }
  1339. [Fact]
  1340. public void ResolvesDataTypeForAssignBinding()
  1341. {
  1342. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1343. {
  1344. var xaml = @"
  1345. <local:AssignBindingControl xmlns='https://github.com/avaloniaui'
  1346. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1347. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1348. x:DataType='local:TestDataContext'
  1349. X='{CompiledBinding StringProperty}' />";
  1350. var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  1351. var compiledPath = ((CompiledBindingExtension)control.X).Path;
  1352. var node = Assert.IsType<PropertyElement>(Assert.Single(compiledPath.Elements));
  1353. Assert.Equal(typeof(string), node.Property.PropertyType);
  1354. }
  1355. }
  1356. [Fact]
  1357. public void ResolvesDataTypeForAssignBinding_FromBindingProperty()
  1358. {
  1359. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1360. {
  1361. var xaml = @"
  1362. <local:AssignBindingControl xmlns='https://github.com/avaloniaui'
  1363. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1364. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1365. X='{CompiledBinding StringProperty, DataType=local:TestDataContext}' />";
  1366. var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml);
  1367. var compiledPath = ((CompiledBindingExtension)control.X).Path;
  1368. var node = Assert.IsType<PropertyElement>(Assert.Single(compiledPath.Elements));
  1369. Assert.Equal(typeof(string), node.Property.PropertyType);
  1370. }
  1371. }
  1372. [Fact]
  1373. public void Uses_RuntimeLoader_Configuration_To_Enabled_Compiled()
  1374. {
  1375. using (UnitTestApplication.Start(TestServices.StyledWindow))
  1376. {
  1377. var xaml = @"
  1378. <local:AssignBindingControl xmlns='https://github.com/avaloniaui'
  1379. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  1380. xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
  1381. X='{Binding StringProperty, DataType=local:TestDataContext}' />";
  1382. var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml, new RuntimeXamlLoaderConfiguration
  1383. {
  1384. UseCompiledBindingsByDefault = true
  1385. });
  1386. var compiledPath = ((CompiledBindingExtension)control.X).Path;
  1387. var node = Assert.IsType<PropertyElement>(Assert.Single(compiledPath.Elements));
  1388. Assert.Equal(typeof(string), node.Property.PropertyType);
  1389. }
  1390. }
  1391. void Throws(string type, Action cb)
  1392. {
  1393. try
  1394. {
  1395. cb();
  1396. }
  1397. catch (Exception e) when (e.GetType().Name == type)
  1398. {
  1399. return;
  1400. }
  1401. throw new Exception("Expected " + type);
  1402. }
  1403. void ThrowsXamlParseException(Action cb) => Throws("XamlParseException", cb);
  1404. void ThrowsXamlTransformException(Action cb) => Throws("XamlTransformException", cb);
  1405. static void PerformClick(Button button)
  1406. {
  1407. button.RaiseEvent(new KeyEventArgs
  1408. {
  1409. RoutedEvent = InputElement.KeyDownEvent,
  1410. Key = Input.Key.Enter,
  1411. });
  1412. }
  1413. }
  1414. public interface INonIntegerIndexer
  1415. {
  1416. string this[string key] { get; set; }
  1417. }
  1418. public interface INonIntegerIndexerDerived : INonIntegerIndexer
  1419. { }
  1420. public interface IHasProperty
  1421. {
  1422. string StringProperty { get; set; }
  1423. }
  1424. public interface IHasPropertyDerived : IHasProperty
  1425. { }
  1426. public interface IHasExplicitProperty
  1427. {
  1428. string ExplicitProperty { get; }
  1429. }
  1430. public class AppendConverter : IValueConverter
  1431. {
  1432. public static IValueConverter Instance { get; } = new AppendConverter();
  1433. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  1434. => string.Format("{0}+{1}", value, parameter);
  1435. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  1436. => throw new NotImplementedException();
  1437. }
  1438. public class TestData
  1439. {
  1440. public string StringProperty { get; set; }
  1441. }
  1442. public class TestDataContextBaseClass {}
  1443. public class TestDataContext : TestDataContextBaseClass, IHasPropertyDerived, IHasExplicitProperty
  1444. {
  1445. public string StringProperty { get; set; }
  1446. public Task<string> TaskProperty { get; set; }
  1447. public IObservable<string> ObservableProperty { get; set; }
  1448. public ObservableCollection<string> ObservableCollectionProperty { get; set; } = new ObservableCollection<string>();
  1449. public string[] ArrayProperty { get; set; }
  1450. public object[] ObjectsArrayProperty { get; set; }
  1451. public List<string> ListProperty { get; set; } = new List<string>();
  1452. public NonIntegerIndexer NonIntegerIndexerProperty { get; set; } = new NonIntegerIndexer();
  1453. public INonIntegerIndexerDerived NonIntegerIndexerInterfaceProperty => NonIntegerIndexerProperty;
  1454. string IHasExplicitProperty.ExplicitProperty => "Hello";
  1455. public string ExplicitProperty => "Bye";
  1456. public class NonIntegerIndexer : NotifyingBase, INonIntegerIndexerDerived
  1457. {
  1458. private readonly Dictionary<string, string> _storage = new Dictionary<string, string>();
  1459. public string this[string key]
  1460. {
  1461. get
  1462. {
  1463. return _storage[key];
  1464. }
  1465. set
  1466. {
  1467. _storage[key] = value;
  1468. RaisePropertyChanged(CommonPropertyNames.IndexerName);
  1469. }
  1470. }
  1471. }
  1472. }
  1473. public class MethodDataContext
  1474. {
  1475. public void Action() { }
  1476. public int Func() => 1;
  1477. public void Action16(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, int i16) { }
  1478. public int Func16(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, int i16) => i;
  1479. public void CustomDelegateTypeVoid(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17) { }
  1480. public int CustomDelegateTypeInt(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17) => i;
  1481. }
  1482. public class MethodAsCommandDataContext : INotifyPropertyChanged
  1483. {
  1484. public event PropertyChangedEventHandler PropertyChanged;
  1485. public string Method() => Value = "Called";
  1486. public string Method1(int i) => Value = $"Called {i}";
  1487. public string Method2(int i, int j) => Value = $"Called {i},{j}";
  1488. public string Value { get; private set; } = "Not called";
  1489. object _parameter;
  1490. public object Parameter
  1491. {
  1492. get
  1493. {
  1494. return _parameter;
  1495. }
  1496. set
  1497. {
  1498. if (_parameter == value)
  1499. {
  1500. return;
  1501. }
  1502. _parameter = value;
  1503. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Parameter)));
  1504. }
  1505. }
  1506. public void Do(object parameter)
  1507. {
  1508. Value = $"Do {parameter}";
  1509. }
  1510. [Metadata.DependsOn(nameof(Parameter))]
  1511. public bool CanDo(object parameter)
  1512. {
  1513. return ReferenceEquals(null, parameter) == false;
  1514. }
  1515. }
  1516. public class CustomDataTemplate : IDataTemplate
  1517. {
  1518. [DataType]
  1519. public Type FancyDataType { get; set; }
  1520. [Content]
  1521. [TemplateContent]
  1522. public object Content { get; set; }
  1523. public bool Match(object data) => FancyDataType?.IsInstanceOfType(data) ?? true;
  1524. public IControl Build(object data) => TemplateContent.Load(Content)?.Control;
  1525. }
  1526. public class CustomDataTemplateInherit : CustomDataTemplate { }
  1527. public class AssignBindingControl : Control
  1528. {
  1529. [AssignBinding] public IBinding X { get; set; }
  1530. }
  1531. }