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

如何在WPF ListBox中绑定数组实现带PackIcon的自定义列表项

看起来你已经搭好了数据源的架子,差的就是给ListBox指定怎么渲染每个MenuItem的模板啦!先帮你修正几个小问题,再给你完整的实现方案:

解决方案

1. 修正C#代码的细节问题

首先你的MenuItem里的Poeition是拼写错误,应该改成Position,不然后续用到这个属性会出问题;另外如果要支持属性变化时UI自动更新,建议给MenuItem类实现INotifyPropertyChanged接口:

// 实现INotifyPropertyChanged的MenuItem类
public class MenuItem : INotifyPropertyChanged
{
    private int _id;
    private string _caption;
    private string _icon;
    private int _position;

    public int Id
    {
        get => _id;
        set { _id = value; OnPropertyChanged(); }
    }

    public string Caption
    {
        get => _caption;
        set { _caption = value; OnPropertyChanged(); }
    }

    public string Icon
    {
        get => _icon;
        set { _icon = value; OnPropertyChanged(); }
    }

    public int Position
    {
        get => _position;
        set { _position = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

// 初始化数据源(修正拼写错误)
MenuItems = new[] 
{ 
    new MenuItem { Id = 0, Caption = "Item 1", Icon = "Pencil", Position = 1 }, 
    new MenuItem { Id = 1, Caption = "Item 2", Icon = "Ticket", Position = 2 } 
};

2. 配置ListBox的ItemTemplate实现图标+文本布局

你当前的XAML只绑定了数据源,但没告诉ListBox每个Item该怎么渲染。我们通过ItemTemplate定义每个ListBoxItem的布局,把PackIcon和文本组合起来:

<ListBox x:Name="lbMenuPanel" 
         Foreground="White" 
         ItemsSource="{Binding MenuItems}" 
         PreviewMouseLeftButtonUp="lbMenuPanel_PreviewMouseLeftButtonUp"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <!-- 定义每个Item的渲染模板 -->
    <ListBox.ItemTemplate>
        <DataTemplate>
            <!-- 横向排列图标和文本 -->
            <StackPanel Orientation="Horizontal" Margin="8" Height="30" VerticalAlignment="Center">
                <!-- 绑定PackIcon的图标类型到MenuItem的Icon属性 -->
                <materialDesign:PackIcon Kind="{Binding Icon}" 
                                         Width="24" 
                                         Height="24" 
                                         Foreground="White" 
                                         Margin="0 0 8 0"/>
                <!-- 绑定文本到MenuItem的Caption属性 -->
                <TextBlock Text="{Binding Caption}" 
                           VerticalAlignment="Center" 
                           FontSize="14"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <!-- 可选:自定义Item的选中/hover样式,优化视觉效果 -->
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Padding" Value="0"/>
            <Setter Property="Background" Value="Transparent"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="#20FFFFFF"/>
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="#30FFFFFF"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

关键注意点

  • 确保你的项目已经安装了MaterialDesignThemes NuGet包(因为用到了PackIcon控件);
  • 记得给ListBox所在的窗口/页面设置DataContext,比如在代码-behind的构造函数里加DataContext = this;(如果MenuItems是在当前类中定义的)。

这样每个ListBoxItem就会独立显示对应的PackIcon和文本啦~

内容的提问来源于stack exchange,提问作者Eugene Oleynikov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:53:55