Browse Source

Add DisplayMemberBinding to ItemsControl

pull/8922/head
Tim 4 years ago
parent
commit
01c6bf4bb7
  1. 6
      src/Avalonia.Controls/Generators/IItemContainerGenerator.cs
  2. 13
      src/Avalonia.Controls/Generators/ItemContainerGenerator.cs
  3. 12
      src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs
  4. 10
      src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs
  5. 19
      src/Avalonia.Controls/ItemsControl.cs
  6. 17
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

6
src/Avalonia.Controls/Generators/IItemContainerGenerator.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Styling; using Avalonia.Styling;
namespace Avalonia.Controls.Generators 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. /// Gets or sets the data template used to display the items in the control.
/// </summary> /// </summary>
IDataTemplate? ItemTemplate { get; set; } IDataTemplate? ItemTemplate { get; set; }
/// <summary>
/// Gets or sets the binding to use to bind to the member of an item used for displaying
/// </summary>
IBinding? DisplayMemberBinding { get; set; }
/// <summary> /// <summary>
/// Gets the ContainerType, or null if its an untyped ContainerGenerator. /// Gets the ContainerType, or null if its an untyped ContainerGenerator.

13
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. /// Gets or sets the data template used to display the items in the control.
/// </summary> /// </summary>
public IDataTemplate? ItemTemplate { get; set; } public IDataTemplate? ItemTemplate { get; set; }
/// <inheritdoc />
public IBinding? DisplayMemberBinding { get; set; }
/// <summary> /// <summary>
/// Gets the owner control. /// Gets the owner control.
@ -189,7 +192,15 @@ namespace Avalonia.Controls.Generators
if (result == null) if (result == null)
{ {
result = new ContentPresenter(); 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) if (ItemTemplate != null)
{ {

12
src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs

@ -53,8 +53,16 @@ namespace Avalonia.Controls.Generators
container.SetValue(ContentTemplateProperty, ItemTemplate, BindingPriority.Style); 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)) if (!(item is IControl))
{ {
container.DataContext = item; container.DataContext = item;

10
src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs

@ -76,7 +76,15 @@ namespace Avalonia.Controls.Generators
result.SetValue(Control.ThemeProperty, ItemContainerTheme, BindingPriority.Style); 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); var itemsSelector = template.ItemsSelector(item);

19
src/Avalonia.Controls/ItemsControl.cs

@ -11,6 +11,7 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.Data;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Metadata; using Avalonia.Metadata;
@ -61,6 +62,23 @@ namespace Avalonia.Controls
public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty = public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty =
AvaloniaProperty.Register<ItemsControl, IDataTemplate?>(nameof(ItemTemplate)); AvaloniaProperty.Register<ItemsControl, IDataTemplate?>(nameof(ItemTemplate));
/// <summary>
/// Defines the <see cref="DisplayMemberBinding" /> property
/// </summary>
public static readonly StyledProperty<IBinding?> DisplayMemberBindingProperty =
AvaloniaProperty.Register<ItemsControl, IBinding?>(nameof(DisplayMemberBinding));
/// <summary>
/// Gets or sets the <see cref="IBinding"/> to use for binding to the display member of each item.
/// </summary>
[AssignBinding]
public IBinding? DisplayMemberBinding
{
get { return GetValue(DisplayMemberBindingProperty); }
set { SetValue(DisplayMemberBindingProperty, value); }
}
private IEnumerable? _items = new AvaloniaList<object>(); private IEnumerable? _items = new AvaloniaList<object>();
private int _itemCount; private int _itemCount;
private IItemContainerGenerator? _itemContainerGenerator; private IItemContainerGenerator? _itemContainerGenerator;
@ -97,6 +115,7 @@ namespace Avalonia.Controls
_itemContainerGenerator.ItemContainerTheme = ItemContainerTheme; _itemContainerGenerator.ItemContainerTheme = ItemContainerTheme;
_itemContainerGenerator.ItemTemplate = ItemTemplate; _itemContainerGenerator.ItemTemplate = ItemTemplate;
_itemContainerGenerator.DisplayMemberBinding = DisplayMemberBinding;
_itemContainerGenerator.Materialized += (_, e) => OnContainersMaterialized(e); _itemContainerGenerator.Materialized += (_, e) => OnContainersMaterialized(e);
_itemContainerGenerator.Dematerialized += (_, e) => OnContainersDematerialized(e); _itemContainerGenerator.Dematerialized += (_, e) => OnContainersDematerialized(e);
_itemContainerGenerator.Recycled += (_, e) => OnContainersRecycled(e); _itemContainerGenerator.Recycled += (_, e) => OnContainersRecycled(e);

17
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -5,6 +5,7 @@ using Avalonia.Collections;
using Avalonia.Controls.Generators; using Avalonia.Controls.Generators;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.Data;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Styling; using Avalonia.Styling;
@ -33,6 +34,12 @@ namespace Avalonia.Controls.Presenters
public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty = public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty =
ItemsControl.ItemTemplateProperty.AddOwner<ItemsPresenterBase>(); ItemsControl.ItemTemplateProperty.AddOwner<ItemsPresenterBase>();
/// <summary>
/// Defines the <see cref="DisplayMemberBinding" /> property
/// </summary>
public static readonly StyledProperty<IBinding?> DisplayMemberBindingProperty =
ItemsControl.DisplayMemberBindingProperty.AddOwner<ItemsPresenterBase>();
private IEnumerable? _items; private IEnumerable? _items;
private IDisposable? _itemsSubscription; private IDisposable? _itemsSubscription;
private bool _createdPanel; private bool _createdPanel;
@ -120,6 +127,15 @@ namespace Avalonia.Controls.Presenters
set { SetValue(ItemTemplateProperty, value); } set { SetValue(ItemTemplateProperty, value); }
} }
/// <summary>
/// Gets or sets the <see cref="IBinding"/> to use for binding to the display member of each item.
/// </summary>
public IBinding? DisplayMemberBinding
{
get { return GetValue(DisplayMemberBindingProperty); }
set { SetValue(DisplayMemberBindingProperty, value); }
}
/// <summary> /// <summary>
/// Gets the panel used to display the items. /// Gets the panel used to display the items.
/// </summary> /// </summary>
@ -177,6 +193,7 @@ namespace Avalonia.Controls.Presenters
{ {
result = new ItemContainerGenerator(this); result = new ItemContainerGenerator(this);
result.ItemTemplate = ItemTemplate; result.ItemTemplate = ItemTemplate;
result.DisplayMemberBinding = DisplayMemberBinding;
} }
result.Materialized += ContainerActionHandler; result.Materialized += ContainerActionHandler;

Loading…
Cancel
Save