0

我正在尝试改进 Winforms 项目,其中数据表行存储在 ListViewItems 的 Tag 属性中。当数据表被重构为 List<T>(或者实际上是包含列表的类)时,如果我可以通过使用 ListView 的子类来使 Tag 属性通用,那将非常有帮助。

在最好的情况下,我希望将 Tag 属性替换为公共 T Tag{get; set;} 包装 base.Tag 并强制转换它。第二个最好的方法是废弃标签并提供像上面一样工作的 TypedTag 之类的新属性。

我认为这将涉及至少 ListView、ListViewItemCollection、SelectedListViewItemCollection 和 ListViewItem 的子类化或复合聚合,我不知道该怎么做。

简而言之:

ListView<Employee> lvwEmployees;

应该导致这成为可能:

Employee selected = lvwEmployees.SelectedItems[0].TypedTag;

并为此给出编译错误:

DataRow selected = lvwEmployees.SelectedItems[0].TypedTag;

是否可以?它已经完成了吗?项目是 dotnet 2.0,但我想如果它有助于解决这个问题,我会尝试升级它。

编辑:事实证明,所有者构造函数参数是某个集合需要连接到内部集合的所有内容。因此,以下工作:

ListView a = new ListView();
a.Items.Add("Hello");
Assert.AreEqual(1, new ListView.ListViewItemCollection(a).Count);

这使得创建通用标记 ListView 变得相当容易。稍后我将发布完整的解决方案。:)

EDIT2:这是解决方案: http: //thecarlr.blogspot.com/2010/11/generic-listview.html

EDIT3:对于设计器支持,只需添加一个非通用子类并使用它。示例:如果您打算在表单中使用 ListView<Employee>,请在另一个文件中创建一个 ListViewEmployee : ListView<Employee>,然后在表单中使用 ListViewEmployee。

添加这些列表视图之一的最简单方法是将普通列表视图添加到表单中,然后在源文件中更改它的类型。(如果您不知道它在哪里声明或实例化,请找出或使用普通的列表视图。)

4

3 回答 3

1

您使错误的类通用。SelectedItems[0] 是 ListViewItem,而不是 ListView。

您无法更改 Items 和 SelectedItems 属性的类型。您当然可以从 ListViewItem 派生您自己的类,然后添加您要存储的属性。不需要另一个 Tag 属性。添加它们不会有任何问题,但是当您从 Selected/Items 集合中检索它们时,您需要将它们转换回派生类。

通常,通过仅将 ListView 用作模型的视图来避免此类代码。然后 ListViewItem.Index 应该总是可以从您的模型中获取类型安全的引用。

于 2010-11-17T18:36:02.787 回答
0

这是解决方案: http: //thecarlr.blogspot.com/2010/11/generic-listview.html

享受 :)

/卡尔

于 2010-11-17T21:16:11.060 回答
0

VS Designer 根本无法处理抽象或通用控件(不是不想问)。

解决该限制的一种方法是围绕标准编写类型安全的包装器ListView

像这样的东西:

public class TypedListView<T> where T : class
{
    public TypedObjectListView(ListView lv) {
        this.lv = lv;
    }
    private ListView lv;

    public virtual T SelectedObject {
        get { return (T)this.lv.SelectedItems[0].Tag; }
    }

    // Lots more methods/properties
}

您在 Designer 中创建一个普通的 ListView,然后当您想要访问它时,您可以创建并使用您的适配器。像这样:

var typedListView = new TypedListView<Employee>(this.listView1);
Employee selectedEmployee = typedListView.SelectedObject;

您需要提供ListView要使用的每个属性或方法的类型化版本。

ObjectListView项目采用这种方法来创建一个TypedObjectListView完全符合您要求的方法。

于 2010-11-18T13:27:36.717 回答