WPF - 使用图标创建列表视图

Jam*_*mes 5 c# wpf

我有一个非常简单的问题.

我有一个ListView控件,我想知道如何在左侧创建一个带有图标的项目.这些项目将在C#中的代码动态添加,而不是通过XAML.

图片样本:这里

与上面类似的东西(不包括Manage Records标题).我设法通过动态创建网格(不使用ListView控件)来完成上面的那个,但我不确定如何控制事件(点击等).

提前致谢.:)

Ale*_*hik 11

解决方案包括覆盖视图项DataTemplate.

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow"
    xmlns:self="clr-namespace:WpfApplication1"
    xmlns:props="clr-namespace:WpfApplication1.Properties">
<Window.Resources>
    <self:ImageConverter x:Key="Conv"/>

    <DataTemplate x:Key="Template">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding Path=Icon, Converter={StaticResource Conv}}"
                   Width="64"
                   Height="64"/>
            <TextBlock Text="{Binding Name}"
                       VerticalAlignment="Center"/>
        </StackPanel>
    </DataTemplate>

</Window.Resources>
<StackPanel>
    <ListView ItemsSource="{Binding Items}" 
              ItemTemplate="{StaticResource Template}"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

然后我们必须在这个视图后面的代码中将PresentationModel设置为视图的DataContext:

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new SampleModel();
    }
Run Code Online (Sandbox Code Playgroud)

正如您在XAML中从绑定表达式中看到的,我们的表示模型应该公开Items属性(如果您考虑在运行时更改Items列表,则底层集合必须是ObservableCollection以便ListView对其更改做出反应):

public class SampleModel 
{
    public IEnumerable<ViewData> Items
    {
        get
        {
            yield return new ViewData(Properties.Resources.airbrush_256, "item 1");
            yield return new ViewData(Properties.Resources.colors_256, "item 2");
            yield return new ViewData(Properties.Resources.distribute_left_edge_256, "item 3");
            yield return new ViewData(Properties.Resources.dossier_ardoise_images, "item 4");
        }
    }
}

public class ViewData
{
    public ViewData(Bitmap icon, string name)
    {
        this._icon = icon;
        this._name = name;
    }

    private readonly Bitmap _icon;
    public Bitmap Icon
    {
        get
        {
            return this._icon;
        }
    }

    private readonly string _name;
    public string Name
    {
        get
        {
            return this._name;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此解决方案中,我将现有的PNG图像添加到Properties.Resources类.然后,图标的类型Bitmap与Source属性类型不兼容,因此我们应该使用下一个转换器将其转换为BitmapSource:

public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Bitmap)
        {
            var stream = new MemoryStream();
            ((Bitmap)value).Save(stream, ImageFormat.Png);

            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.StreamSource = stream;
            bitmap.EndInit();

            return bitmap;
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,您可以使用pack uri来存储图标而不是资源.然后,您的ViewData类将公开Uri类型的属性(而不是Bitmap).然后不需要转换器.