web-dev-qa-db-ja.com

C#の継承と基本プロパティのオーバーライド

現在、カスタムListViewItemクラスが必要です。これをMyListViewItemと呼びましょう。各アイテムにいくつかの追加データを関連付け、Checkedプロパティが変更されたときにいくつかの操作を実行する必要があります。私はいくつかのことを試しましたが、現在、関連するコードは次のようになっています。

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) {
        // ...
    }
}

私が抱えている問題は、ListViewでアイテムのチェックボックスをクリックしても、セッターが呼び出されないことです。誰かが私が間違っていることを知っていますか?親ListViewのItemCheckedイベントを使用できることは承知していますが、それははるかにクリーンなソリューションではないようです。 (また、実際にはオブジェクトをコンストラクターに渡していませんが、その部分はここでは重要ではありません)。

13

「new」キーワードは単に「hides」をオーバーライドしないため、機能していません。

これは、MyListViewItemの型定義を通じて参照されるオブジェクトのインスタンスでCheckedを呼び出すと、willコードを実行することを意味します。ただし、ListViewはListViewItemの型定義を介してこのオブジェクトを参照するため、「新しい」メソッドは呼び出されません。

「新規」はnotオーバーライドです。より良い解決策は、おそらくカスタムリストビューでコードを処理することです。それほど醜いわけではありません。

18
Quibblesome

newoverridebaseメンバーではありません。同じ名前の新しいメソッドを宣言します。 VB.NETでは、Shadowsと呼ばれます。

実際、newは、コンパイラの警告をオフにする以外は何もしません。 overrideとして宣言しないメンバー(およびbaseメンバーがvirtualまたはoverrideの場合にのみこれを行うことができます)は、 baseメンバーの継承ツリー。

9
Mehrdad Afshari

ListViewItem.Checkedプロパティが仮想であると仮定すると、それをオーバーライドする必要があります。

public override bool Checked
3
John Saunders

ListViewItem.Checkedプロパティは仮想ではないため(MSDNドキュメント ここ を参照)、この方法でその動作をオーバーライドすることはできません。動作を変更するには、イベントを使用するか、ListViewから派生し、 ListView.OnItemChecked をオーバーライドする必要があります。

1
Brian ONeil

独自のカスタムListViewItemを作成する代わりに、カスタムデータを含む個別のタイプを作成してから、各ListViewItemタグプロパティにカスタムデータへの参照を割り当ててみませんか?

これは私が以前から使用しているパターンであり、非常にうまく機能します。項目がチェックされたときのカスタムアクションについては、リストビューで関連するイベントを処理するだけです。

1
Robert Venables