diff --git a/samples/ControlCatalog/Pages/ComboBoxPage.xaml b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
index 025b85492c..d440b7cce3 100644
--- a/samples/ControlCatalog/Pages/ComboBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
@@ -1,12 +1,20 @@
+ xmlns:sys="using:System"
+ xmlns:col="using:System.Collections">
ComboBoxA drop-down list.
-
+
+
+
+ Inline ItemsInline Item 2
@@ -14,6 +22,24 @@
Inline Item 4
+
+
+
+
+ Hello
+ World
+
+
+
+
+
+
+
+
+
+
+
+
@@ -46,7 +72,7 @@
-
+
diff --git a/src/Avalonia.Base/Utilities/TypeUtilities.cs b/src/Avalonia.Base/Utilities/TypeUtilities.cs
index 9f2308a062..179ded3549 100644
--- a/src/Avalonia.Base/Utilities/TypeUtilities.cs
+++ b/src/Avalonia.Base/Utilities/TypeUtilities.cs
@@ -93,13 +93,25 @@ namespace Avalonia.Utilities
return !type.IsValueType || IsNullableType(type);
}
+ ///
+ /// Returns a value indicating whether value can be casted to the specified type.
+ /// If value is null, checks if instances of that type can be null.
+ ///
+ /// The type to cast to
+ /// The value to check if cast possible
+ /// True if the cast is possible, otherwise false.
+ public static bool CanCast(object value)
+ {
+ return value is T || (value is null && AcceptsNull(typeof(T)));
+ }
+
///
/// Try to convert a value to a type by any means possible.
///
- /// The type to cast to.
- /// The value to cast.
+ /// The type to convert to.
+ /// The value to convert.
/// The culture to use.
- /// If successful, contains the cast value.
+ /// If successful, contains the convert value.
/// True if the cast was successful, otherwise false.
public static bool TryConvert(Type to, object value, CultureInfo culture, out object result)
{
@@ -216,10 +228,10 @@ namespace Avalonia.Utilities
/// Try to convert a value to a type using the implicit conversions allowed by the C#
/// language.
///
- /// The type to cast to.
- /// The value to cast.
- /// If successful, contains the cast value.
- /// True if the cast was successful, otherwise false.
+ /// The type to convert to.
+ /// The value to convert.
+ /// If successful, contains the converted value.
+ /// True if the convert was successful, otherwise false.
public static bool TryConvertImplicit(Type to, object value, out object result)
{
if (value == null)
@@ -278,8 +290,8 @@ namespace Avalonia.Utilities
/// Convert a value to a type by any means possible, returning the default for that type
/// if the value could not be converted.
///
- /// The value to cast.
- /// The type to cast to..
+ /// The value to convert.
+ /// The type to convert to..
/// The culture to use.
/// A value of .
public static object ConvertOrDefault(object value, Type type, CultureInfo culture)
@@ -291,8 +303,8 @@ namespace Avalonia.Utilities
/// Convert a value to a type using the implicit conversions allowed by the C# language or
/// return the default for the type if the value could not be converted.
///
- /// The value to cast.
- /// The type to cast to..
+ /// The value to convert.
+ /// The type to convert to.
/// A value of .
public static object ConvertImplicitOrDefault(object value, Type type)
{
diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs
index 472727823a..1a46d84558 100644
--- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs
@@ -327,7 +327,11 @@ namespace Avalonia.Controls.Presenters
var oldChild = Child;
var newChild = content as IControl;
- if (content != null && newChild == null)
+ // We want to allow creating Child from the Template, if Content is null.
+ // But it's important to not use DataTemplates, otherwise we will break content presenters in many places,
+ // otherwise it will blow up every ContentPresenter without Content set.
+ if (newChild == null
+ && (content != null || ContentTemplate != null))
{
var dataTemplate = this.FindDataTemplate(content, ContentTemplate) ??
(
diff --git a/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs b/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs
index 4a6a1c6cfb..8e7b290247 100644
--- a/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs
+++ b/src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs
@@ -1,5 +1,7 @@
using System;
+using Avalonia.Utilities;
+
namespace Avalonia.Controls.Templates
{
///
@@ -16,7 +18,7 @@ namespace Avalonia.Controls.Templates
///
/// Whether the control can be recycled.
public FuncDataTemplate(Func build, bool supportsRecycling = false)
- : base(typeof(T), CastBuild(build), supportsRecycling)
+ : base(o => TypeUtilities.CanCast(o), CastBuild(build), supportsRecycling)
{
}
@@ -63,7 +65,7 @@ namespace Avalonia.Controls.Templates
/// The weakly typed function.
private static Func