Наследование С# и переопределение базовых свойств
В настоящее время мне нужен пользовательский класс 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 ссылку на пользовательские данные?
Это шаблон, который я использовал в течение некоторого времени, и он работает очень хорошо. Что касается пользовательских действий, когда элементы отмечены, просто обработайте соответствующие события в представлении списка.