Наследование С# и переопределение базовых свойств

В настоящее время мне нужен пользовательский класс 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, мой сеттер никогда не вызывается. Кто-нибудь знает, что я делаю неправильно? Я знаю, что я мог бы использовать событие ItemChecked родительского ListView, но это похоже на гораздо менее чистое решение. (Также я фактически не передаю объект конструктору, но эта часть здесь не важна).

Ответы

Ответ 1

Это не работает, потому что "новое" ключевое слово не отменяет его, просто "скрывает".

Это означает, что если вы вызываете Checked в экземпляре объекта, на который ссылается определение типа MyListViewItem, вы запустите свой код. Однако ListView ссылается на этот объект с помощью определения типа ListViewItem и поэтому не будет называть ваш "новый" метод.

"новый" не переопределяется. Лучшее решение - это, вероятно, обработать код в пользовательском представлении списка. На самом деле это не так уродливо.

Ответ 2

new не override член base. Он объявляет новый метод с тем же именем. В VB.NET он называется Shadows.

Действительно, new ничего не делает, кроме выключения предупреждения компилятора. Член, которого вы не объявляете как override (и вы можете сделать это, только если член base virtual или override) будет полностью не связан с деревом наследования члена base.

Ответ 3

Предполагая, что свойство ListViewItem. Checked является виртуальным, вам необходимо переопределить его:

public override bool Checked

Ответ 4

Свойство ListViewItem.Checked не является виртуальным (см. документ MSDN здесь), поэтому вы не сможете переопределить его поведение в сюда. Вам нужно будет использовать событие или получить из ListView и переопределить ListView.OnItemChecked, чтобы изменить поведение.

Ответ 5

Вместо создания собственного пользовательского ListViewItem, почему бы не создать отдельный тип, который должен содержать ваши пользовательские данные, а затем назначить каждому свойству тега ListViewItem ссылку на пользовательские данные?

Это шаблон, который я использовал в течение некоторого времени, и он работает очень хорошо. Что касается пользовательских действий, когда элементы отмечены, просто обработайте соответствующие события в представлении списка.