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

时间:2016-02-05 12:13:32

标签: c# wpf image gridview

我想使用ExpandoObject中的数据添加一行,类似于Dictionary<string, object>string是列的标题,object的值是列的值。 每当我获得新数据时,我都会创建一个新的GridView,因为列数可能不同。 List myItems中的所有行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 });
                }
            }

在此之后我尝试添加行:

            foreach (dynamic item in myItems)
            {
                this.listView.Items.Add(item);
            }

我尝试修改此solution用于其他目的。如果我只想添加string类型的值,此解决方案非常有效,但现在我还想在gridview中显示image,但如果我在gridview中添加一个,它会显示我只是:

  

“System.Windows.Controls.Image”

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

编辑:在之前的方法中,据说我需要创建一个新的DataTemplate来显示图片,但没有一个解决方案(Solution 1Solution 2)我发现这对我有用。

2 个答案:

答案 0 :(得分:2)

最好的方法是在资源中为Icon列定义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>

<强> 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);
        }

    }
}

<强>结果

enter image description here

答案 1 :(得分:1)

我怀疑您是否能够在您使用的方法中使您的解决方案具有通用性。它适用于具有适合您的有效ToString()表示的基于文本的数据类型。对于使用复杂数据类型(如Images),您可能必须使用Templates,如Shadowed所述,您必须为每种复杂类型设置不同的属性。例如,对于图像,它可以是按钮的大小和来源 - 背景颜色。作为一个选项,您可以创建某种模板工厂并应用CellTemplateSelector,它将为您提供nesseccary模板,但正如您所说 - 它是一种全新的方式。