FuncDataTemplate.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Reactive.Linq;
  5. namespace Avalonia.Controls.Templates
  6. {
  7. /// <summary>
  8. /// Builds a control for a piece of data.
  9. /// </summary>
  10. public class FuncDataTemplate : FuncTemplate<object, IControl>, IDataTemplate
  11. {
  12. /// <summary>
  13. /// The default data template used in the case where no matching data template is found.
  14. /// </summary>
  15. public static readonly FuncDataTemplate Default =
  16. new FuncDataTemplate<object>(
  17. (data, s) =>
  18. {
  19. if (data != null)
  20. {
  21. var result = new TextBlock();
  22. result.Bind(
  23. TextBlock.TextProperty,
  24. result.GetObservable(Control.DataContextProperty).Select(x => x?.ToString()));
  25. return result;
  26. }
  27. else
  28. {
  29. return null;
  30. }
  31. },
  32. true);
  33. /// <summary>
  34. /// The implementation of the <see cref="Match"/> method.
  35. /// </summary>
  36. private readonly Func<object, bool> _match;
  37. /// <summary>
  38. /// Initializes a new instance of the <see cref="FuncDataTemplate"/> class.
  39. /// </summary>
  40. /// <param name="type">The type of data which the data template matches.</param>
  41. /// <param name="build">
  42. /// A function which when passed an object of <paramref name="type"/> returns a control.
  43. /// </param>
  44. /// <param name="supportsRecycling">Whether the control can be recycled.</param>
  45. public FuncDataTemplate(
  46. Type type,
  47. Func<object, INameScope, IControl> build,
  48. bool supportsRecycling = false)
  49. : this(o => IsInstance(o, type), build, supportsRecycling)
  50. {
  51. }
  52. /// <summary>
  53. /// Initializes a new instance of the <see cref="FuncDataTemplate"/> class.
  54. /// </summary>
  55. /// <param name="match">
  56. /// A function which determines whether the data template matches the specified data.
  57. /// </param>
  58. /// <param name="build">
  59. /// A function which returns a control for matching data.
  60. /// </param>
  61. /// <param name="supportsRecycling">Whether the control can be recycled.</param>
  62. public FuncDataTemplate(
  63. Func<object, bool> match,
  64. Func<object, INameScope, IControl> build,
  65. bool supportsRecycling = false)
  66. : base(build)
  67. {
  68. Contract.Requires<ArgumentNullException>(match != null);
  69. _match = match;
  70. SupportsRecycling = supportsRecycling;
  71. }
  72. /// <inheritdoc/>
  73. public bool SupportsRecycling { get; }
  74. /// <summary>
  75. /// Checks to see if this data template matches the specified data.
  76. /// </summary>
  77. /// <param name="data">The data.</param>
  78. /// <returns>
  79. /// True if the data template can build a control for the data, otherwise false.
  80. /// </returns>
  81. public bool Match(object data)
  82. {
  83. return _match(data);
  84. }
  85. /// <summary>
  86. /// Determines of an object is of the specified type.
  87. /// </summary>
  88. /// <param name="o">The object.</param>
  89. /// <param name="t">The type.</param>
  90. /// <returns>
  91. /// True if <paramref name="o"/> is of type <paramref name="t"/>, otherwise false.
  92. /// </returns>
  93. private static bool IsInstance(object o, Type t)
  94. {
  95. return t.IsInstanceOfType(o);
  96. }
  97. }
  98. }