You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avalonia UI:程序化/XAML自定义ListBox默认配置的实现咨询

AvaloniaUI 自定义DirectoryListBox:两种默认属性配置方案

我正在AvaloniaUI中创建自定义用户控件DirectoryListBox(继承自ListBox),需要为它设置默认的SelectionMode、ItemsPanelTemplate、ListBoxItem样式和DataTemplate。现有基础代码及目标XAML结构如下:

基础C#类

using Avalonia.Controls;

namespace WFClient.Controls;

public class DirectoryListBox : ListBox
{
    public DirectoryListBox()
    {
        // 待填充默认配置
    }
}

目标XAML结构(期望的默认效果)

<ListBox SelectionMode="Multiple,Toggle">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.Styles>
        <Style Selector="ListBoxItem">
            <Setter Property="Width" Value="125"/>
            <Setter Property="Height" Value="50"/>
            <Setter Property="Margin" Value="3"/>
            <Setter Property="Padding" Value="0"/>
        </Style>
    </ListBox.Styles>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BoxShadow="0 0 2 2 LightGray" Margin="3">
                <!-- 自定义内容 -->
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

问题1:是否优先采用程序化方式实现?若可行,具体操作方法是什么?

两种方案都可行,程序化方式适合将控件逻辑完全封装在C#类中,无需依赖外部XAML资源。具体实现如下:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Styling;

namespace WFClient.Controls;

public class DirectoryListBox : ListBox
{
    public DirectoryListBox()
    {
        // 设置选择模式
        SelectionMode = SelectionMode.Multiple | SelectionMode.Toggle;

        // 设置ItemsPanel为WrapPanel
        ItemsPanel = new ItemsPanelTemplate(() => new WrapPanel());

        // 添加ListBoxItem的默认样式
        var listBoxItemStyle = new Style(x => x.OfType<ListBoxItem>());
        listBoxItemStyle.Setters.Add(new Setter(WidthProperty, 125.0));
        listBoxItemStyle.Setters.Add(new Setter(HeightProperty, 50.0));
        listBoxItemStyle.Setters.Add(new Setter(MarginProperty, new Thickness(3)));
        listBoxItemStyle.Setters.Add(new Setter(PaddingProperty, new Thickness(0)));
        Styles.Add(listBoxItemStyle);

        // 添加默认DataTemplate
        ItemTemplate = new FuncDataTemplate<object>((_, __) =>
        {
            return new Border
            {
                BoxShadow = Avalonia.Media.Shadow.Parse("0 0 2 2 LightGray"),
                Margin = new Thickness(3),
                Child = new ContentPresenter()
            };
        });
    }
}

问题2:是否可在应用资源中通过XAML定义该控件?若可行,具体操作方法是什么?

可以,这种方式更适合集中管理样式和模板,视觉结构更直观。步骤如下:

  1. 在应用资源文件(如App.xaml或单独的Styles.xaml)中,针对DirectoryListBox定义全局样式,设置所有默认属性。
  2. 自定义控件类保持简洁,无需在构造函数中添加配置代码。

示例:App.xaml中添加资源

<Application xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="clr-namespace:WFClient.Controls"
             x:Class="WFClient.App">
    <Application.Styles>
        <FluentTheme Mode="Light"/>
        
        <!-- 自定义DirectoryListBox的默认样式 -->
        <Style Selector="controls|DirectoryListBox">
            <!-- 设置选择模式 -->
            <Setter Property="SelectionMode" Value="Multiple,Toggle"/>
            
            <!-- 设置ItemsPanel -->
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <WrapPanel/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
            
            <!-- 设置ItemTemplate -->
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Border BoxShadow="0 0 2 2 LightGray" Margin="3">
                            <!-- 自定义内容 -->
                        </Border>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            
            <!-- 添加ListBoxItem的样式 -->
            <Style Selector="ListBoxItem">
                <Setter Property="Width" Value="125"/>
                <Setter Property="Height" Value="50"/>
                <Setter Property="Margin" Value="3"/>
                <Setter Property="Padding" Value="0"/>
            </Style>
        </Style>
    </Application.Styles>
</Application>

简化后的DirectoryListBox类

using Avalonia.Controls;

namespace WFClient.Controls;

public class DirectoryListBox : ListBox
{
    // 无需额外构造函数代码,所有默认配置由XAML资源提供
}

内容的提问来源于stack exchange,提问作者Christopher Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:27:45