.NET ListView列顺序问题

时间:2010-02-08 21:30:43

标签: .net listview

我在表单中遇到问题,我按以下顺序向.NET ListView控件添加了列:

A   | B   | C   | D

列A-D的显示索引按顺序为0-3,但它们显示的顺序错误:

A   | B   | D   | C
            ^-----^  these are switched at runtime

注意:在设计时,一切看起来都像我想要的那样。

我想,但我不知道为什么,这是因为我在添加了列D之后将列C添加到了ListView中。我在列编辑器对话框中将其移动了一个档位,调整了显示索引,并且检查.Designer.cs文件中的创建顺序,按顺序检查所有内容的顺序。

然而问题仍然存在。

另请注意:这不仅仅是标题标签问题,还会交换列,包括其数据。数据按照我希望显示的顺序添加,但最后两列是交换的。

我需要检查什么才能弄清楚为什么我的一个列处于错误的位置?

我弄明白了这个问题。由于某种原因,即使我在对话框中设置了DisplayIndex属性,也不会保留它。

如果我完全关闭了表单,并在Visual Studio中重新打开它,那么它就会转移。显然,对话框编辑器没有将这些属性检测为“已更改”,因此保存机制也不关心为我保存它。

添加列的代码如下:

this.lvResult = new System.Windows.Forms.ListView();
this.colResultId = new System.Windows.Forms.ColumnHeader();
this.colResultTitle = new System.Windows.Forms.ColumnHeader();
this.colResultLanguage = new System.Windows.Forms.ColumnHeader();
this.colResultTags = new System.Windows.Forms.ColumnHeader();
// 
// lvResult
// 
this.lvResult.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
            | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
this.lvResult.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.colResultId,
this.colResultTitle,
this.colResultLanguage,
this.colResultTags});
this.lvResult.FullRowSelect = true;
this.lvResult.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvResult.HideSelection = false;
this.lvResult.Location = new System.Drawing.Point(12, 6);
this.lvResult.Name = "lvResult";
this.lvResult.Size = new System.Drawing.Size(466, 117);
this.lvResult.TabIndex = 0;
this.lvResult.UseCompatibleStateImageBehavior = false;
this.lvResult.View = System.Windows.Forms.View.Details;
this.lvResult.SelectedIndexChanged += new System.EventHandler(this.lvResult_SelectedIndexChanged);
// 
// colResultId
// 
this.colResultId.Text = "#";
this.colResultId.Width = 35;
// 
// colResultTitle
// 
this.colResultTitle.Text = "Title";
this.colResultTitle.Width = 220;
// 
// colResultTags
// 
this.colResultTags.DisplayIndex = 2;
this.colResultTags.Text = "Tags";
this.colResultTags.Width = 100;
// 
// colResultLanguage
// 
this.colResultLanguage.Text = "Language";

当我直接在文件中添加缺少的属性时,它可以工作。

11 个答案:

答案 0 :(得分:6)

我使用Visual Studio 2010时遇到了这个问题。当我查看设计器生成的代码时,它只为某些列设置了DisplayIndex。在设计时,列的顺序正确,但在运行时它们的顺序不同。当我添加我的列时,他们仍然拥有设计器生成的名称,例如ColumnHeader1等。当我将它们重命名为更有意义的名称并运行我的应用程序时,运行时列顺序是正确的。我查看了设计器生成的代码,发现它重新排序了列创建代码并删除了所有DisplayIndex值(因为它们不需要)

答案 1 :(得分:5)

它是否可能会持续存在于表单的.resx而不是.designer?我无法想象为什么它会这样做,但是是啊......

如果所有其他方法都失败了,请尝试从表单中删除ListView。然后,在你的项目中创建一个新的垃圾表单,在垃圾表单上重新创建ListView,测试垃圾表单以确保你没有得到奇怪的巫毒行为,然后将ListView从垃圾表单复制回你的真实表单?

非常令人费解,我知道......

答案 2 :(得分:1)

有一种方法可以做到这一点,移动为ListView生成的设计时代码及其列,然后将它们推送到方法中......请参阅此处以获取示例

public Mainform(){
    InitializeComponent();
    //
    InitListView();
}

public void InitListView(){
    // Design time generated code and manually add it here.
}

这是处理奇怪的设计时间问题的废话....唯一的障碍是,如果你想添加另一列,你将不会在设计时看到它...

希望这有帮助, 最好的祝福, 汤姆。

答案 3 :(得分:1)

错误仍然存​​在于 VS 2019 中(天哪)。我发现只需更改(名称)字段之一,然后单击“确定”关闭编辑器,然后重新打开编辑器并将名称更改回原来的名称即可修复它。

答案 4 :(得分:0)

除了移动成员之外,还需要重置DisplayIndex。 将C列的DisplayIndex设置为3,将D的DisplayIndex设置为4

答案 5 :(得分:0)

我编辑设计器并手动为每列DisplayIndex属性编写。 建立良好,运行良好。虽然现在我看到设计师有点变化,但对我来说它运作正常。

答案 6 :(得分:0)

我在Visual Studio 2017中遇到了同样的问题。在设计时,它们的顺序正确。但是在运行时,最后两列被切换了。

最终为我修复的是进入列表视图任务(显示在列表视图右上角的小按钮)并将视图更改为大图标。运行该项目。退出。返回并将视图更改为Details并运行它。这为我解决了。

答案 7 :(得分:0)

要在Visual Studio 2015中向ListView控件添加列并使列与其值正确对齐,以便它们不会移动,请按照下列步骤操作:

  1. 转到Visual Studio中的表单。
  2. 单击ListView控件右上角的智能标记。 (小箭头)。
  3. 单击“编辑列”。
  4. 将打开ColumnHeader Collection Editor对话框。
  5. 单击“添加”按钮。
  6. columnHeader1将在“成员”框中显示旁边带有数字。
  7. 现在查看属性框,“成员”框旁边的框,然后在“行为”下查找“DisplayIndex”。如果未显示DisplayIndex,请单击“行为”旁边的箭头以显示它。
  8. DisplayIndex中的数字将与columnHeader1的数量相匹配。
  9. 注意“成员”框和属性框之间的两个大而粗的黑色箭头。一个是向上移动,另一个是向下移动。
  10. 如果要将columnHeader1(您的新列)移动到其他位置,请选择它,然后单击大的粗体黑色向上箭头或大的粗体黑色向下箭头将其定位到您想要的位置出现在ListView控件中。
  11. 当您向上或向下移动columnHeader1时,旁边的数字将会更改,但DisplayIndex中的数字将保持不变。不好! columnHeader1编号必须与DisplayIndex编号匹配。
  12. 更改DisplayIndex编号,使其与columnHeader1的编号匹配。如果columnHeader1旁边的数字现在为2,则将DisplayIndex更改为2.只需确保它们都具有相同的数字。
  13. 现在在属性框中查找Design下的Name,并将columnHeader1的名称更改为新列所需的名称。
  14. 现在在杂项下查找文字。并将ColumnHeader更改为新列所需的名称。
  15. 单击“确定”。新列将位于您种植的位置,并在其下方显示正确的值。

答案 8 :(得分:0)

Visual Studio中ListView Designer的实际行为有点令人困惑。但是一旦你理解了它,它就会变得容易多了。这是一个例子:

enter image description here

ColumnHeader Collection Editor对话框左侧显示的成员列表 必须 对应于您的代码用于添加SubItems的顺序。例如,这是我的代码:

    mImageList.Images.Add(_IconImage);
    ListViewItem Item = new ListViewItem("", mImageList.Images.Count - 1);
    Item.SubItems.Add(_ImageBase64);
    Item.SubItems.Add(_Description);
    Item.SubItems.Add(_Name);
    lvIconList.Items.Add(Item);

请注意,在创建项目时,我还创建了第一个子项目(0),其中包含“”作为文本,并指向我要为其显示的图像。回顾上面的编辑器图片,你可以看到我已经调用了这个 IconImage 并给它一个DisplayIndex为0.上面的代码现在按照上面显示的顺序添加子项:base64文本,描述和名称。按特定顺序。此代码以及成员 下显示的列的顺序必须 匹配,1:1。

现在,DisplayIndex会告诉您这些显示的顺序。您可以看到第一个的DisplayIndex为0.在上面的图片中查看,您可以看到“Name”为2nd,然后“Encoded Value”为3rd,最后“Description是列标题中的第4个。表示“EncodedText”的DisplayIndex为2,因为这是我希望它显示的位置。接下来,“Description”的DisplayIndex将为3.而“ItemName”的DisplayIndex将为1.

这就是这样做的。您不必删除所有内容并重新开始整个编码过程。您所要做的就是了解DisplayIndex实际上做什么

会员 必须 的排序方式与您在代码中添加()的方式相同。你对这个细节没有任何选择。然后,DisplayIndex只是告诉ListView显示器上这些字段的顺序。

假设我的上述代码存在以下功能:

    Func<int, int> U = int idx => lvIconList.Columns.OfType<ColumnHeader>
            .Where(a => a.DisplayIndex == idx).Select(a => a.Index).Sum();

然后标题将按以下顺序显示:

    for (int i = 0; i <= lvIconList.Columns.Count - 1; i++) {
        Console.WriteLine(lvIconList.Columns(UU(i)).Text);
    }

花了一点时间来使用。

答案 9 :(得分:-1)

我知道如何解决这个问题,你需要重建项目,它会再次出色。

答案 10 :(得分:-1)

我偶尔会遇到这个问题,但只有当我对项目进行了很多更改并在ListView中的其他列之前插入列时。

我发现三个单独的修复工作,但没有一个工作。但是,以下一直对我有用:

  1. 将中间的任何列向上移动然后向下移动。
  2. 重建项目Build&gt;&gt; Rebuild
  3. 关闭然后重新打开项目
  4. 我发现每次都没有(1)和(2)都有效,而没有做(3)会导致无序状态在下次打开时返回。