简体   繁体   English

ListView以编程方式添加列显示项目类型

[英]ListView programatically added columns shows type of item

I got a ListView in another assembly and want to add a column to it. 我在另一个程序集中得到了一个ListView,并希望为其添加一个列。 The items in the listview are objects of a class in that assembly. 列表视图中的项是该程序集中类的对象。

When I add a column like this 当我添加这样的列

var col : GridViewColumn = new GridViewColumn();
col.Header = "Header text";
list.View.Columns.Add(col);

the column appears but all rows in the listview have the name of the type of the item in that new column. 列出现但列表视图中的所有行都具有该新列中项目类型的名称。 Even when I change the value of the new column ( itemclass.Items[newColIdx] = "zz" ) this does not display. 即使我更改新列的值( itemclass.Items[newColIdx] = "zz" ),也不会显示。 There is no data binding or cell templates involved. 没有涉及数据绑定或细胞模板。

Why is that? 这是为什么?

Edit : Maybe I can enhance the question: If a ListView.Items contains an array of class A - how do you control which things of A are displayed how in the GridView? 编辑 :也许我可以增强问题:如果ListView.Items包含A类数组 - 如何在GridView中控制A的哪些内容? I am in the need of reverse engineering here and DisplayMemberBinding is null so it does not use data binding AFAIK. 我需要逆向工程,DisplayMemberBinding为null,因此它不使用数据绑定AFAIK。

Bounty Question : When ToString() is called on every item (which represents a row), how is that mapped towards the columns of the GridView? 赏金问题 :当每个项目(代表一行)调用ToString() ,它是如何映射到GridView的列的? How must I alter an item in the row so that the new column is filled? 如何更改行中的项目以便填充新列?

Special problem when trying to find this solution is that this runs in a JScript sandbox within a bigger C# .NET application and no debugging possibility is supplied other than using message boxes and reflection. 尝试找到此解决方案时的特殊问题是,它在较大的C#.NET应用程序中的JScript沙箱中运行,除了使用消息框和反射之外,不提供任何调试可能性。

Edit : The problem is that I am writing a JScript which runs in a 3rd party .NET application and gives me the opportunity to do many things possible with .NET. 编辑 :问题是我正在编写一个在第三方.NET应用程序中运行的JScript,并让我有机会用.NET做很多事情。 This is a script adding features to a listview. 这是一个向listview添加功能的脚本。 I can access the listview and it is filled with database data by the 3rd party app. 我可以访问listview,它由第三方应用程序填充数据库数据。 I do not know how it does that. 我不知道它是怎么做到的。 I can programatically add custom rows with custom content (not DB related). 我可以以编程方式添加带有自定义内容的自定义行(而不是与DB相关)。 But when I add a custom column I do not seem to be able to se its value in den rows. 但是当我添加一个自定义列时,我似乎无法在den行中查看它的值。

The added rows are of a type 3rdParty.ListRow and contain a property Items to which I assign a string array. 添加的行的类型为3rdParty.ListRow并包含一个属性Items ,我为其分配一个字符串数组。 The values of the array are displayed in the representative columns - but not in the added columns. 数组的值显示在代表列中 - 但不会显示在添加的列中。 There I only get the text 3rdParty.ListRow which is because ToString() was called on the ListRow. 在那里我只得到文本3rdParty.ListRow ,这是因为在ListRow上调用了ToString()

So: How can I tell the new columns (eg index 5) to display ListRow.Items[5] and not ListRow.ToString() ? 那么:我如何告诉新列(例如索引5)显示ListRow.Items[5]而不是ListRow.ToString() I liked to do it the same way the already existing columns do it seems that all the properties Alex mentioned are undefined there. 我喜欢以与现有列相同的方式执行此操作,似乎Alex提到的所有属性都未定义。 How would I set DataMemberBinding to achieve mapping to ListRow.Items[5] ? 我如何设置DataMemberBinding以实现到ListRow.Items[5]映射?

That's because the ToString() method of each items in the list is being called. 那是因为正在调用列表中每个项的ToString()方法。 If not overridden by the inheriting type, Object.ToString() returns the object's type name. 如果未被继承类型覆盖,Object.ToString()将返回对象的类型名称。

There's another issue where your list won't raise change events so the UI doesn't know the data has changed and needs to refresh. 还有一个问题,您的列表不会引发更改事件,因此UI不知道数据已更改并需要刷新。

If column doesn't have DisplayMemberBinding or CellTemplate then ToString is called on each item in the grid and evaluated value is used as cell content. 如果列没有DisplayMemberBindingCellTemplate则在网格中的每个项目上调用ToString,并将计算值用作单元格内容。

For example, if you have class: 例如,如果你有课程:

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public override string ToString()
    {
        return LastName;
    }
}

If you bind a collection of Person to the grid view: 如果将Person的集合绑定到网格视图:

var people =
    new List<Person>
    {
        new Person { FirstName = "Peter", LastName = "Smith" }, 
        new Person { FirstName = "Steve", LastName = "White" },
        new Person { FirstName = "Dave", LastName = "Gates" },
    };

listView1.ItemsSource = people;

And if you create a new column without binding, then LastName will be shown in this column, because overridden ToString() returns LastName . 如果您创建一个没有绑定的新列,那么LastName将显示在此列中,因为重写的ToString()将返回LastName If you change ToString to return FirstName then new column will show FirstName . 如果更改ToString以返回FirstName则新列将显示FirstName

Hope I understood your question correctly. 希望我能正确理解你的问题。

[Edit] [编辑]

If you add many new columns and don't use DisplayMemberBinding then all the new columns will evaluate and show ToString() result. 如果添加许多新列并且不使用DisplayMemberBinding则所有新列都将评估并显示ToString()结果。 You need to set DisplayMemberBinding to show particular property. 您需要设置DisplayMemberBinding以显示特定属性。

var newColumn = new GridViewColumn();
newColumn.Header = "Test";
newColumn.DisplayMemberBinding = new Binding("FirstName");
gridView.Columns.Add(newColumn);

[Edit] Answers to your questions: [编辑]你的问题的答案:

When ToString() is called on every item (which represents a row), how is that mapped towards the columns of the GridView? 当在每个项目(表示一行)上调用ToString()时,如何将其映射到GridView的列? How must I alter an item in the row so that the new column is filled? 如何更改行中的项目以便填充新列?

ToString is called when cell presenter is rendered, unless you specified binding or template, which would also use binding in the end. 呈现单元格展示器时会调用ToString,除非您指定了绑定或模板,最后也会使用绑定。 You cannot alter row item to control how it is represented in the grid, unless you override ToString or properties that are bound to the columns. 除非重写ToString或绑定到列的属性,否则不能更改行项以控制它在网格中的表示方式。

Not sure I understand your problem completely. 不确定我完全理解你的问题。 You are adding a new column, right? 你正在添加一个新列,对吗? Why don't you set DisplayMemberBinding property on your column? 为什么不在列上设置DisplayMemberBinding属性? If you do this you will be able to show in the column whatever you want. 如果您这样做,您将能够在列中显示您想要的任何内容。

[Edit] [编辑]

I think I answered your bounty question :). 我想我回答了你的赏金问题:)。 I think I already earned the bounty :). 我想我已经获得了赏金:)。

However, here is the answer to your next question: 但是,这是您下一个问题的答案:

How would I set DataMemberBinding to achieve mapping to ListRow.Items[5]? 我如何设置DataMemberBinding以实现到ListRow.Items [5]的映射?

The answer: 答案:

newColumn.DisplayMemberBinding = new Binding("Items[5]");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM