【问题标题】:ListView programatically added columns shows type of itemListView 以编程方式添加的列显示项目的类型
【发布时间】:2011-03-07 10:06:42
【问题描述】:

我在另一个程序集中有一个 ListView,并想向它添加一列。列表视图中的项目是该程序集中某个类的对象。

当我添加这样的列时

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

该列出现,但列表视图中的所有行都具有该新列中项目类型的名称。即使我更改了新列 (itemclass.Items[newColIdx] = "zz") 的值,它也不会显示。不涉及数据绑定或单元格模板。

这是为什么呢?

编辑:也许我可以加强这个问题:如果 ListView.Items 包含 A 类的数组 - 你如何控制 A 的哪些东西在 GridView 中如何显示?我需要在这里进行逆向工程,并且 DisplayMemberBinding 为空,因此它不使用数据绑定 AFAIK。

赏金问题:当ToString() 对每个项目(代表一行)调用时,它是如何映射到 GridView 的列的?我必须如何更改行中的项目以填充新列?

尝试找到此解决方案时的特殊问题是,它在更大的 C# .NET 应用程序内的 JScript 沙箱中运行,并且除了使用消息框和反射之外没有提供任何调试可能性。

编辑:问题是我正在编写一个在第 3 方 .NET 应用程序中运行的 JScript,它让我有机会用 .NET 做很多可能的事情。这是一个向列表视图添加功能的脚本。我可以访问列表视图,它由第 3 方应用程序填充数据库数据。我不知道它是怎么做到的。我可以以编程方式添加具有自定义内容的自定义行(与数据库无关)。但是当我添加一个自定义列时,我似乎无法在 den 行中设置它的值。

添加的行的类型为3rdParty.ListRow,并包含一个属性Items,我为其分配了一个字符串数组。数组的值显示在代表列中 - 但不在添加的列中。那里我只得到文本 3rdParty.ListRow 这是因为 ToString() 在 ListRow 上被调用。

那么:如何告诉新列(例如索引 5)显示 ListRow.Items[5] 而不是 ListRow.ToString()?我喜欢以与现有列相同的方式执行此操作,似乎 Alex 提到的所有属性都在那里未定义。如何设置DataMemberBinding 实现映射到ListRow.Items[5]

【问题讨论】:

  • 看起来虽然你的赏金问题得到了回答,但你不会放弃赏金。只是不公平。
  • 刚出国。颁发赏金。感谢您的帮助。
  • 谢谢。希望它对你有用。
  • @Alex - 我现在了解机制,在我的最后一条评论中,我要求举个例子:“我将如何做到这一点,以便它绑定到 ListRow.Items[5] 而不是 ListRow.ToString( )(就像现在发生的那样)?”那么,如果您有任何线索,我将分配给 DisplayMemberBinding 什么。我看到无法从现有列中获取它。如果你不知道我会暂时离开这个问题。
  • 那么,newColumn.DisplayMemberBinding = new Binding("Items[5]"); 没用?

标签: c# wpf listview datagridview jscript.net


【解决方案1】:

如果列没有DisplayMemberBindingCellTemplate,则对网格中的每个项目调用 ToString,并将评估值用作单元格内容。

例如,如果你有课:

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

    public string LastName { get; set; }

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

如果您将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;

如果您创建一个没有绑定的新列,则 LastName 将显示在此列中,因为覆盖ToString() 返回LastName。如果您将ToString 更改为返回FirstName,则新列将显示FirstName

希望我正确理解了您的问题。

[编辑]

如果您添加许多新列并且不使用DisplayMemberBinding,则所有新列都将评估并显示ToString() 结果。 您需要设置DisplayMemberBinding 以显示特定属性。

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

[编辑] 回答您的问题:

当 ToString() 在每个 item(代表一行),如何 映射到的列 网格视图?我必须如何更改项目 行,以便新列是 满了?

在渲染单元格演示器时调用ToString,除非您指定绑定或模板,最后也会使用绑定。您无法更改行项目以控制其在网格中的表示方式,除非您覆盖 ToString 或绑定到列的属性。

不确定我是否完全理解您的问题。您正在添加一个新列,对吗?为什么不在列上设置 DisplayMemberBinding 属性?如果您这样做,您将能够在列中显示您想要的任何内容。

[编辑]

我想我回答了你的赏金问题:)。我想我已经赢得了赏金:)。

但是,这是您下一个问题的答案:

如何设置 DataMemberBinding 以实现到 ListRow.Items[5] 的映射?

答案:

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

【讨论】:

  • 所以GridViewColumn对象上一定有DisplayMemberBindingCellTemplate?否则在项目上调用.ToString()(导致多个新列都显示相同的内容)?我会试试看。
  • 你确定这是唯一的可能性吗?在我的现有列中,DisplayMemberBindingCellTemplate 都是 null,但这些列的内容不同。
  • CellStyleSelector 怎么样?另外,网格是否应用了样式?
  • CellStyleSelector 也是null。 ListView 有样式,而 GridView (list.View) 没有。 ListView 的样式有 0 个触发器,但有 10 个设置器(与列数不匹配)。希望这可以帮助。您需要更多信息吗?
  • 不确定我是否完全理解您的问题。您正在添加一个新列,对吗?为什么不在列上设置 DisplayMemberBinding 属性?如果您这样做,您将能够在列中显示您想要的任何内容。
【解决方案2】:

这是因为正在调用列表中每个项目的 ToString() 方法。如果没有被继承类型覆盖,Object.ToString() 返回对象的类型名称。

还有一个问题是您的列表不会引发更改事件,因此 UI 不知道数据已更改并需要刷新。

【讨论】:

  • 所以 ItemObject.ToString() 被调用为网格视图的每一列和“旧”列返回值?列号是怎么传的?
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
相关资源
最近更新 更多