diff --git a/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs index f9772cb399..79c77f2519 100644 --- a/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/IItemContainerGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Avalonia.Controls.Templates; +using Avalonia.Data; using Avalonia.Styling; namespace Avalonia.Controls.Generators @@ -24,6 +25,11 @@ namespace Avalonia.Controls.Generators /// Gets or sets the data template used to display the items in the control. /// IDataTemplate? ItemTemplate { get; set; } + + /// + /// Gets or sets the binding to use to bind to the member of an item used for displaying + /// + IBinding? DisplayMemberBinding { get; set; } /// /// Gets the ContainerType, or null if its an untyped ContainerGenerator. diff --git a/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs index 8b36b07cec..42f0124295 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerGenerator.cs @@ -45,6 +45,9 @@ namespace Avalonia.Controls.Generators /// Gets or sets the data template used to display the items in the control. /// public IDataTemplate? ItemTemplate { get; set; } + + /// + public IBinding? DisplayMemberBinding { get; set; } /// /// Gets the owner control. @@ -189,7 +192,15 @@ namespace Avalonia.Controls.Generators if (result == null) { result = new ContentPresenter(); - result.SetValue(ContentPresenter.ContentProperty, item, BindingPriority.Style); + if (DisplayMemberBinding is not null) + { + result.SetValue(StyledElement.DataContextProperty, item, BindingPriority.Style); + result.Bind(ContentPresenter.ContentProperty, DisplayMemberBinding, BindingPriority.Style); + } + else + { + result.SetValue(ContentPresenter.ContentProperty, item, BindingPriority.Style); + } if (ItemTemplate != null) { diff --git a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs index 3ff1b0702d..5e965a9d04 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs @@ -53,8 +53,16 @@ namespace Avalonia.Controls.Generators container.SetValue(ContentTemplateProperty, ItemTemplate, BindingPriority.Style); } - container.SetValue(ContentProperty, item, BindingPriority.Style); - + if (DisplayMemberBinding is not null) + { + container.SetValue(StyledElement.DataContextProperty, item, BindingPriority.Style); + container.Bind(ContentProperty, DisplayMemberBinding, BindingPriority.Style); + } + else + { + container.SetValue(ContentProperty, item, BindingPriority.Style); + } + if (!(item is IControl)) { container.DataContext = item; diff --git a/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs b/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs index 4e3deb5552..9f9845b14f 100644 --- a/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs +++ b/src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs @@ -76,7 +76,15 @@ namespace Avalonia.Controls.Generators result.SetValue(Control.ThemeProperty, ItemContainerTheme, BindingPriority.Style); } - result.SetValue(ContentProperty, template.Build(item), BindingPriority.Style); + if (DisplayMemberBinding is not null) + { + result.SetValue(StyledElement.DataContextProperty, item, BindingPriority.Style); + result.Bind(ContentProperty, DisplayMemberBinding, BindingPriority.Style); + } + else + { + result.SetValue(ContentProperty, item, BindingPriority.Style); + } var itemsSelector = template.ItemsSelector(item); diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 345e7fcac8..e9ce7912a7 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -11,6 +11,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Controls.Utils; +using Avalonia.Data; using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Metadata; @@ -61,6 +62,23 @@ namespace Avalonia.Controls public static readonly StyledProperty ItemTemplateProperty = AvaloniaProperty.Register(nameof(ItemTemplate)); + + /// + /// Defines the property + /// + public static readonly StyledProperty DisplayMemberBindingProperty = + AvaloniaProperty.Register(nameof(DisplayMemberBinding)); + + /// + /// Gets or sets the to use for binding to the display member of each item. + /// + [AssignBinding] + public IBinding? DisplayMemberBinding + { + get { return GetValue(DisplayMemberBindingProperty); } + set { SetValue(DisplayMemberBindingProperty, value); } + } + private IEnumerable? _items = new AvaloniaList(); private int _itemCount; private IItemContainerGenerator? _itemContainerGenerator; @@ -97,6 +115,7 @@ namespace Avalonia.Controls _itemContainerGenerator.ItemContainerTheme = ItemContainerTheme; _itemContainerGenerator.ItemTemplate = ItemTemplate; + _itemContainerGenerator.DisplayMemberBinding = DisplayMemberBinding; _itemContainerGenerator.Materialized += (_, e) => OnContainersMaterialized(e); _itemContainerGenerator.Dematerialized += (_, e) => OnContainersDematerialized(e); _itemContainerGenerator.Recycled += (_, e) => OnContainersRecycled(e); diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs index 2821fa8cf0..836433cdf8 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs @@ -5,6 +5,7 @@ using Avalonia.Collections; using Avalonia.Controls.Generators; using Avalonia.Controls.Templates; using Avalonia.Controls.Utils; +using Avalonia.Data; using Avalonia.LogicalTree; using Avalonia.Styling; @@ -33,6 +34,12 @@ namespace Avalonia.Controls.Presenters public static readonly StyledProperty ItemTemplateProperty = ItemsControl.ItemTemplateProperty.AddOwner(); + /// + /// Defines the property + /// + public static readonly StyledProperty DisplayMemberBindingProperty = + ItemsControl.DisplayMemberBindingProperty.AddOwner(); + private IEnumerable? _items; private IDisposable? _itemsSubscription; private bool _createdPanel; @@ -120,6 +127,15 @@ namespace Avalonia.Controls.Presenters set { SetValue(ItemTemplateProperty, value); } } + /// + /// Gets or sets the to use for binding to the display member of each item. + /// + public IBinding? DisplayMemberBinding + { + get { return GetValue(DisplayMemberBindingProperty); } + set { SetValue(DisplayMemberBindingProperty, value); } + } + /// /// Gets the panel used to display the items. /// @@ -177,6 +193,7 @@ namespace Avalonia.Controls.Presenters { result = new ItemContainerGenerator(this); result.ItemTemplate = ItemTemplate; + result.DisplayMemberBinding = DisplayMemberBinding; } result.Materialized += ContainerActionHandler;