Avalonia中使用UniformGrid作为ItemsPanel

本意是想在Avalonia中实现一个类似按钮组的单选控件,同时又想展示所有的选项。

最后决定采用附加属性的方式实现,让ItemsControl具备UniformGrid的能力 

最终效果如图

ItemsControlAttached代码如下
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Interactivity;
namespace Infrastructure.Avalonia.Attachment;
public class ItemsControlAttached : AvaloniaObject
{
    static ItemsControlAttached()
    {
        UseGridProperty.Changed.AddClassHandler<Interactive>(HandleUseGridChanged);
    }
    private static void HandleUseGridChanged(Interactive arg1, AvaloniaPropertyChangedEventArgs arg2)
    {
        if (arg1 is ItemsControl ic && arg2.NewValue is bool useGrid && useGrid)
        {
            var uniformGrid = new UniformGrid();
        
            // 直接设置属性
            uniformGrid.Rows = GetRows(ic);
            uniformGrid.Columns = GetColumns(ic);

            // 添加事件处理器以在属性更改时更新 UniformGrid
            ic.GetObservable(RowsProperty).Subscribe(rows => uniformGrid.Rows = rows);
            ic.GetObservable(ColumnsProperty).Subscribe(columns => uniformGrid.Columns = columns);

            // 设置 ItemsPanel
            ic.ItemsPanel = new FuncTemplate<Panel>(() => uniformGrid);
        }
    }
    public static readonly AttachedProperty<int> RowsProperty =
        AvaloniaProperty.RegisterAttached<ListBox, int>(
            "Rows", typeof(ItemsControlAttached));

    public static readonly AttachedProperty<int> ColumnsProperty =
        AvaloniaProperty.RegisterAttached<ListBox, int>(
            "Columns", typeof(ItemsControlAttached));

    public static readonly AttachedProperty<bool> UseGridProperty =
        AvaloniaProperty.RegisterAttached<ListBox, bool>(
            "UseGrid", typeof(ItemsControlAttached));

    public static int GetRows(AvaloniaObject element) => element.GetValue(RowsProperty);
    public static void SetRows(AvaloniaObject element, int value) => element.SetValue(RowsProperty, value);
    public static int GetColumns(AvaloniaObject element) => element.GetValue(ColumnsProperty);
    public static void SetColumns(AvaloniaObject element, int value) => element.SetValue(ColumnsProperty, value);

    public static bool GetUseGrid(AvaloniaObject element) => element.GetValue(UseGridProperty);
    public static void SetUseGrid(AvaloniaObject element, bool value) => element.SetValue(UseGridProperty, value);
}

使用代码如下

     <TabItem Header="GridListBox">
            <UniformGrid Columns="2">
                <UniformGrid.Styles>
                    <Style Selector="ListBox">
                        <Setter Property="BorderBrush" Value="Orange"></Setter>
                        <Setter Property="BorderThickness" Value="1"></Setter>
                        <Setter Property="ItemTemplate" >
                            <Setter.Value>
                                <DataTemplate>
                                    <Button Content="{Binding}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"></Button>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </UniformGrid.Styles>
                <ListBox ItemsSource="{Binding GridListBoxSource}"></ListBox>
                <ListBox ItemsSource="{Binding GridListBoxSource}" attachment:ItemsControlAttached.UseGrid="True" attachment:ItemsControlAttached.Rows="2"></ListBox>
            </UniformGrid>
        </TabItem>
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值