【问题标题】:inherited ListViewItem in WinForms, C#, .Net2.0在 WinForms、C#、.Net2.0 中继承 ListViewItem
【发布时间】:2012-11-16 07:17:19
【问题描述】:

我在 System.Windows.Forms 中遇到了 ListView 的问题,我无法自己处理它,请求帮助或提示我哪里做错了?
说明:
- 我有一个类 - 将其命名为 cListViewItem('c' 来自自定义),它继承自标准 ListViewItem,但存储我自己的数据处理类。现在,在使用 ListView.items.Add( ) 将 cListViewItem 添加到 ListView 类之后,我似乎无法控制项目的名称。
- 我的源代码片段(为了这篇文章的目的而改变了)

using System.Windows.Forms;
cListViewItem:ListViewItem
{
  // gives a basic idea
  public cListViewItem( myclass DataStorage )
  {
    // constructor only stores DataStorage to a local variable for further use;
    this._storage = DataStorage;
  }
  protected myclass _storage;
  // and there goes the fun:
  // I thought that ListView class uses .Text property when drawing items, but that is not truth
  // my idea was to 'cheat' a little with:
  new public String Text
  {
    get
    {
      // overriding a getter should be enough i thought, but i was wrong
      return( some string value from DataStorage class passed via constructor );
      // setter is not rly needed here, because data comes from this._storage class;
      // in later stages i've even added this line, to be informed whenever it's called ofc before return( ); otherwise VisualStudio would not compile
      MessageBox.Show( "Calling item's .Text property" );
      // guess what? this message box NEVER shows up;
    }
  }
}

我看到使用 .Text setter 很重要,但构造函数是我能做到的最后一刻,在创建 cListViewItem 之后,它被添加到 ListView Items 属性并显示,所以没有地方再次调用 .Text = "" .
只有当我在 cListViewItem 的构造函数中设置所有内容时,我的代码才有效,例如:

public cListViewItem( myclass DataStorage )
{
   this._storage = DataStorage;
   this.Text = DataStorage.String1;
   // and if I add subitems here, I will see em when the ListView.View property be changed  to View.Details
}

那我是瞎了还是怎么了?当我使用 cListViewItem.Text = "string" 我会看到 'string' 在 ListView 但当我只是覆盖 .Text getter 我看不到项目:(

ListView 类提供了以我需要的方式显示项目的灵活性。我想创建一个类,将我的自定义数据存储类与 ListView 类绑定。在我的应用程序的下一阶段,我想为 ListView 中的选定项目绑定一个表单,这将允许我更改项目(我的自定义类)的值。这就是为什么我想让每个 ListViewItems 项记住相应的自定义数据存储类。
ListView 中显示的名称永远不会是唯一的,因此允许多个相同的名称,但项目会因 id 值而不同(数据库方面);
我只是想不通为什么使用 ListViewItem.Text 设置器来完成这项工作,尽管 ListView 类不使用 ListViewItem.Text 获取器来显示项目(我的 MessageBox 永远不会弹出)??
请帮忙。

【问题讨论】:

    标签: c# listview


    【解决方案1】:

    这里的主要问题是您使用 new 关键字隐藏了属性。原始属性不是virtual(“可覆盖”),因此它不会被覆盖而是被遮蔽。

    阅读here了解更多信息。

    【讨论】:

      【解决方案2】:

      如果我理解正确,那么以下几点可能会有所帮助。

      为了存储自定义数据,您实际上不需要从 ListViewItem 类派生,而是可以使用 ListViewItem 的实例并将 Tag 属性设置为任何对象,这可以是您的 DataStorage 类。如果你这样做,那么在你构建 ListViewItem 之后设置它的文本

      DataStorage storage = GetDataStorage();  
      ListViewItem item = new ListViewItem(storage.Name);
      item.Tag = storage;
      

      如果要继承 ListViewItem 则在构造函数中设置值

      public cListViewItem( myclass DataStorage )
      {
          // constructor only stores DataStorage to a local variable for further use;
          this._storage = DataStorage;
          this.Text = this._storage.Name;
      }
      

      属性和方法隐藏至少让我自己有点困惑,我不太记得规则,但最终自动完成的对 Text 的调用不会调用你的版本......

      【讨论】:

      • 提示太多了,你是对的 - 这是规则。如果 ListView 使用从我的 cListViewItem 到 ListView 的转换就足够了,这是使用基类的方法(属性)。无论我使用 .Tag 属性还是派生类,我仍然必须使用 .Text setter。泰
      • @KrzysztofP:太好了,如果可以解决问题,请将其标记为答案,然后帮助他人,欢迎来到 StackOverflow。
      猜你喜欢
      • 2019-12-01
      • 2016-09-28
      • 2010-11-22
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多