将列添加到包含图像的列表视图

dan*_*l59 7 c# wpf gridview image

我想使用a中的数据添加一行ExpandoObject,类似于a Dictionary<string, object>.的string是列的报头和所述object的值是该列的值.每当我获得新数据时,我都会创建一个新数据GridView,因为列数可能不同.在ListmyItems中是所有行Dictionary<string, object>,我想在我的视图中显示.

这是我将列添加到视图中的方式:

            List<Column> columns = new List<Column>();

            myItemValues = (IDictionary<string, object>)myItems[0];
            // Key is the column, value is the value
            foreach (var pair in myItemValues)
            {
                Column column = new Column();
                column.Title = pair.Key;
                column.SourceField = pair.Key;
                columns.Add(column);
            }
            view.Columns.Clear();
            foreach (var column in columns)
            {
                Binding binding = new Binding(column.SourceField);
                if (column.SourceField == "Icon")
                {
                    view.Columns.Add(new GridViewColumn
                    {
                        Header = column.Title,
                        DisplayMemberBinding = binding,
                        CellTemplate = new DataTemplate(typeof(Image))
                    });
                }
                else
                {
                    view.Columns.Add(new GridViewColumn { Header = column.Title, DisplayMemberBinding = binding });
                }
            }
Run Code Online (Sandbox Code Playgroud)

在此之后我尝试添加行:

            foreach (dynamic item in myItems)
            {
                this.listView.Items.Add(item);
            }
Run Code Online (Sandbox Code Playgroud)

我试图为其他目的修改此解决方案.这个解决方案效果非常好,如果我只想添加类型的值string,但现在我也想image在gridview中显示一个,但如果我在gridview中添加一个,它只显示:

"System.Windows.Controls.Image"

现在我想知道,如果我可以修改我的代码,以便我可以在gridview中显示任何类型(或至少imagesstrings),或者我必须使用完全新的方式,并且会是这样的?

编辑:在之前的方法中,据说,我需要创建一个新的DataTemplate来显示图像,但我找到的解决方案(解决方案1,解决方案2)都没有为我工作.

Ant*_*lov 2

最好的方法是在资源中为图标列定义DataTemplate,然后在为图标创建列时加载它。我修改了您的代码以展示该方法。

XAML

<Window x:Class="ListViewIcon.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewIcon"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="iconTemplate">
                <Image Source="{Binding Icon}"
                   Width="64"
                   Height="64"/>
            </DataTemplate>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <ListView x:Name="myListView"></ListView>

    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

C#

public class Column
{
    public string Title { get; set; }
    public string SourceField { get; set; }
}

public partial class MainWindow : Window
{
    private BitmapImage LoadImage()
    {
        var img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri(@"D:\image.png", UriKind.Absolute);
        img.CacheOption = BitmapCacheOption.OnLoad;
        img.EndInit();

        return img;
    }

    public MainWindow()
    {
        InitializeComponent();

        GridView gridView = new GridView();
        this.myListView.View = gridView;

        List<dynamic> myItems = new List<dynamic>();
        dynamic myItem;
        IDictionary<string, object> myItemValues;

        var image = LoadImage();

        // Populate the objects with dynamic columns
        for (var i = 0; i < 100; i++)
        {
            myItem = new System.Dynamic.ExpandoObject();

            foreach (string column in new string[] { "Id", "Name", "Something" })
            {
                myItemValues = (IDictionary<string, object>)myItem;
                myItemValues[column] = "My value for " + column + " - " + i;
            }

            myItem.Icon = image;

            myItems.Add(myItem);
        }

        // Assuming that all objects have same columns - using first item to determine the columns
        List<Column> columns = new List<Column>();

        myItemValues = (IDictionary<string, object>)myItems[0];

        // Key is the column, value is the value
        foreach (var pair in myItemValues)
        {
            Column column = new Column();

            column.Title = pair.Key;
            column.SourceField = pair.Key;

            columns.Add(column);
        }

        // Add the column definitions to the list view
        gridView.Columns.Clear();

        foreach (var column in columns)
        {

            if (column.SourceField == "Icon")
            {
                gridView.Columns.Add(new GridViewColumn
                {
                    Header = column.Title,
                    CellTemplate = FindResource("iconTemplate") as DataTemplate
                });
            }
            else
            {
                var binding = new Binding(column.SourceField);
                gridView.Columns.Add(new GridViewColumn { Header = column.Title, DisplayMemberBinding = binding });
            }


        }

        // Add all items to the list
        foreach (dynamic item in myItems)
        {
            this.myListView.Items.Add(item);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述