2009-05-13 11 views
13

Ich habe derzeit eine benutzerdefinierte ListViewItem Klasse - nennen wir es MyListViewItem. Es müssen einige zusätzliche Daten mit jedem Element verknüpft sein und einige Vorgänge ausgeführt werden, wenn die Checked-Eigenschaft geändert wird. Ich habe einige Dinge ausprobiert, aber zur Zeit der entsprechende Code sieht wie folgt aus:C# Vererbung und überschreiben Basiseigenschaften

class MyListViewItem : ListViewItem { 
    new public bool Checked { 
     get { 
      return base.Checked; 
     } 
     set { 
      base.Checked = value; 
      // do some other things here based on value 
     } 
    } 
    public MyListViewItem(Object otherData) { 
     // ... 
    } 
} 

Das Problem, das ich habe, ist, dass, wenn ich auf das Kontrollkästchen der Artikel klicken Sie in der Listview, meine Setter nie aufgerufen. Weiß jemand was ich falsch mache? Ich bin mir bewusst, dass ich das ItemChecked-Ereignis des übergeordneten ListView verwenden könnte, aber das scheint wie eine viel weniger saubere Lösung. (Ich gebe auch kein Objekt an den Konstruktor, aber dieser Teil ist hier nicht wichtig).

+0

Nun, wenn jemand interessiert ist, endete ich die Interaktion zwischen meinen Daten und der Checked-Eigenschaft im Getter/Setter für die benutzerdefinierten Daten. Nicht sicher, warum ich vorher nicht daran gedacht hatte. – jnylen

Antwort

18

Es ist nicht Sache der „neuen“ Schlüsselwort arbeiten außer Kraft setzen es nicht nur „versteckt“.

Das bedeutet, wenn Sie Checked für eine Instanz des Objekts, das durch die Typdefinition von MyListViewItem referenziert wird, Ihren Code ausführen. Das ListView verweist jedoch über die Typdefinition von ListViewItem auf dieses Objekt und ruft daher Ihre "neue" Methode nicht auf.

"neu" ist nicht überschreiben. Die bessere Lösung ist wahrscheinlich, den Code in einer benutzerdefinierten Listenansicht zu behandeln. Es ist nicht wirklich so hässlich.

+0

Das mache ich gerade im list_ItemChecked-Handler. Ich glaube nicht, dass es eine benutzerdefinierte ListView garantiert, also werde ich einfach auf base.Checked schauen, bevor ich etwas mit meinen benutzerdefinierten Daten machen möchte. Vielen Dank. – jnylen

+0

[Toller Artikel zu diesem Thema] (http://broadcast.oreilly.com/2009/10/understanding-c-using-virtual.html) – Amicable

8

new nicht override die base Mitglied. Es deklariert eine neue Methode mit demselben Namen. In VB.NET heißt es Shadows.

In der Tat, new macht nichts außer Ausschalten einer Compiler-Warnung. Das Mitglied, das Sie nicht als override deklarieren (und Sie können dies nur tun, wenn das base-Mitglied virtual oder override ist), ist völlig unabhängig von der Vererbungsstruktur des Elements base.

3

Angenommen, dass die ListViewItem. Checked Eigenschaft ist virtuell, müssen Sie es außer Kraft zu setzen:

public override bool Checked 
+0

Es ist nicht virtuell. Ich denke, ich muss einfach etwas anderes machen. Vielen Dank! – jnylen

1

Die ListViewItem.Checked Eigenschaft nicht virtuell ist (siehe MSDN doc here), so dass Sie außer Kraft setzen können, um das Verhalten der es auf diese Weise nicht. Sie müssen das Ereignis verwenden oder von ListView ableiten und ListView.OnItemChecked überschreiben, um das Verhalten zu ändern.

1

Anstatt ein eigenes benutzerdefiniertes ListViewItem zu erstellen, erstellen Sie einen separaten Typ für Ihre benutzerdefinierten Daten und weisen Sie dann jeder ListViewItem-Tag-Eigenschaft einen Verweis auf die benutzerdefinierten Daten zu.

Dies ist das Muster, das ich seit einiger Zeit verwende und es funktioniert sehr gut. Wie bei benutzerdefinierten Aktionen, wenn Elemente aktiviert sind, behandeln Sie einfach die relevanten Ereignisse in der Listenansicht.