Является ли пользовательский `RadioButtonList` основанным на` ListBox` необходимым в WPF?
Я унаследовал проект, который использует RadioButtonList
, который наследует от ListBox
. Он был снят с Интернета (в настоящее время он не может найти ссылку) и содержит RadioButtonList.cs(который содержит шесть свойств зависимостей) и RadioButtonList.xaml(это только стили и шаблоны управления).
Этот элемент управления используется в более чем ста местах. Это вызывает проблемы, потому что это не полный и профессиональный контроль. Такие проблемы, как проблемы с фокусом, клавиатура и т.д. (См. Комментарии.)
После долгих исследований в разное время за последние пару лет кажется, что этот контроль действительно не нужен. Все, что нужно, - установить свойство GroupName
в группе радиокнопки. И единственная причина, по которой используется элемент управления RadioButtonList
, - это помочь с привязкой данных к списку опций через наследуемый ListBox
.
1) Действительно ли этот контроль необходим? Есть ли лучший способ?
2) Есть ли профессиональный контроль, open-source или иное, что позволит мне получить преимущества привязки данных без головных болей? (Мы используем Infragistics и DevExpress, но я не знаком со всеми элементами управления, предлагаемыми этими наборами.)
Мои ответы
1a) Действительно ли этот контроль необходим?
- Если вам нужен только один список переключателей, тогда этот элемент управления не нужен.
- Если ваше приложение использует множество списков переключателей, тогда да, этот элемент управления необходим.
- Если вы используете список переключателей в разных приложениях, то да, возможно, этот элемент управления необходим.
1b) Есть ли лучший способ?
- Я говорю, что вывод из
ListBox
, ItemsControl
или что-то другое, создавая стили и шаблоны, - единственный способ создать этот элемент управления; поэтому нет лучшего способа.
2) Есть ли профессиональный контроль...
- Определенно,
ListBoxEdit
с RadioListBoxEditStyleSettings
.
Комментарии относительно ответов
Все ответы указывают, что создание элемента управления RadioButtonList
не требуется. Тем не менее, если вам нужно больше, чем несколько списков радиокнопок, к моменту создания стилей и шаблонов управления и, возможно, шаблона данных вы получите коллекцию артефактов кода, которую можно назвать радиокнопочным списком, контроль. Поэтому, на мой взгляд, необходим a RadioButtonList
.
Кроме того, мое понимание - это RadioButtonList
, было сброшено в раннем WPF CTP. Что я могу понять из-за ограниченной потребности в таком контроле, который можно легко создать.
Комментарий относительно принятого ответа
2) Есть ли профессиональный контроль...
- Определенно,
ListBoxEdit
с RadioListBoxEditStyleSettings
.
Последний комментарий к Mike Strobel Отвечать
RadioButtonList
, который у меня есть, является конечным результатом его ответа. Хотя я хорош в создании пользовательских элементов управления, я предпочитаю, чтобы сторонние производители компонентов, такие как Infragistics и DevExpress, создавали и поддерживали базовый элемент управления, подобный этому.
Ответы
Ответ 1
Я могу только сказать вам, что DevExpress использует ListBoxEdit
с RadioListBoxEditStyleSettings
для представления группы RadioButtons. Практически это то же самое, что и ваш контроль, который вы используете, но я думаю, что он обеспечивает лучшую функциональность и хорошо тестируется. RadioButton не предоставляется DevExpress, и в моем приложении я использую Default RadionButton-Control, предоставляемый WPF/Silverlight.
Вы используете RadioListBoxEdit для DevExpress следующим образом:
<dxe:ListBoxEdit SelectedItem={Binding CheckItem, Mode=TwoWay}>
<dxe:ListBoxEdit.StyleSettings>
<dxe:RadioListBoxEditStyleSettings />
</dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>
Более подробную информацию о ListBoxEdit из DevExpress можно найти здесь
Ответ 2
Действительно ли этот контроль необходим? Есть ли лучший способ?
Как указывает @lawc, нет, это необязательно. Однако это может быть предпочтительным, в зависимости от того, какой уровень гибкости вы желаете. Многоразовый стиль достаточно прост для создания, но выполнение его "правильно" немного более активно, чем просто настройка пользовательского ItemTemplate
.
Использование стилей
An ItemsControl
в WPF переносит свои элементы в соответствующие контейнеры. Каждый из элементов управления селектора в основном WPF переопределяет логику, которая определяет, может ли элемент служить в качестве своего собственного контейнера, а также код factory, который создает контейнеры для новых элементов. Например, ListBox
будет обертывать каждый из своих элементов в ListBoxItem
(если сам элемент уже не является ListBoxItem
). Стиль, применяемый к этим контейнерам, может быть установлен для родительского ItemsControl
через свойство ItemContainerStyle
. Это отличается от свойства ItemTemplate
, что позволяет вам контролировать внешний вид элемента в контейнере. Более конкретно, он переопределяет шаблон содержимого, примененный к ContentPresenter
внутри контейнера.
Так как a RadioButton
не получается из ListBoxItem
, просто установка ItemTemplate
приведет к созданию списка элементов управления RadioButton
, встроенных в элементы управления ListBoxItem
, что означает, что они все равно будут иметь тот же самый хром, который обычно ассоциируется с элементами управления ListBox
и, возможно, некоторыми макетами и фокусными странностями. Вероятно, это не то, что вы хотите.
Вместо этого переопределите ItemContainerStyle
и используйте его для назначения пользовательского шаблона ListBoxItem
, который вставляет RadioButton
. Вероятно, вам удастся избежать установки свойства GroupName
, что устраняет возможные столкновения имен. Вместо этого просто установите двустороннюю привязку между свойством RadioButton.IsChecked
и шаблоном родительским свойством ListBoxItem.IsSelected
.
Чтобы использовать эту технику удобно, обычно создается ресурс Style
(доступный в масштабе всего приложения), который может быть применен к соответствующим экземплярам ListBox
, и который устанавливает ItemContainerStyle
. Кроме того, вы можете сделать стиль контейнера доступным как глобальный ресурс и установить его в своих экземплярах ListBox
. В любом случае вам нужно установить свойство.
Использование пользовательского элемента управления
В то время как евангелисты WPF часто повторяют философию предпочтения пользовательских стилей над пользовательскими элементами управления, на практике это не всегда удобно. Возможно, вам будет удобнее создавать RadioButtonList
, который расширяет элемент управления ListBox
, а затем дает ему стиль по умолчанию, который автоматически применяет пользовательский стиль, описанный выше. Это избавит вас от необходимости вручную назначать стиль списка или стиль контейнера на каждом экземпляре ListBox
, но это не огромная победа.
Но, возможно, вам нужно немного больше контролировать внешний вид элементов RadioButton
. Например, вы можете:
- Отрегулируйте маржу вокруг "пули" каждого элемента
RadioButton
;
- Отрегулируйте вертикальное выравнивание маркеров относительно содержимого;
- Поддержка горизонтальной и вертикальной ориентации;
- Автоматически отключать содержимое
RadioButton
для элементов, которые не выбраны.
Создание собственной реализации, скорее всего, полученной из ListBox
, позволяет легко добавлять эти функции, даже если вы уже используете свой список радиостанций в своем приложении. Это можно сделать и с помощью вышеописанной техники, хотя для этого может потребоваться присоединенное поведение или некоторые приложенные свойства, и в этом случае вы получите несколько фрагментированный дизайн.
Сторонние решения
Есть ли профессиональный контроль, с открытым исходным кодом или иным образом, который позволит мне получить преимущества привязки данных без головных болей?
Это не необычный случай использования, и я не сомневаюсь, что вокруг него есть некоторые реализации. Некоторые из них могут быть в фреймворках с открытым исходным кодом, а некоторые из них могут быть извлечены из приложений с открытым исходным кодом. Что касается сторонних реализаций, я знаю, что Actipro отправляет RadioButtonList
в свою общую библиотеку WPF, которая включена во все их компонентов WPF. Когда последний раз я проверял, он был недоступен сам по себе. Тем не менее, он поддерживает все дополнительные функции, перечисленные выше.
Ответ 3
По-моему, вам не нужен этот контроль.
Вы можете просто использовать .Net ListBox для достижения всех существующих функций.
- Используя ListBox.ItemsSource, вы можете привязать данные к вашей коллекции опций
- Укажите ListBox.ItemTemplate, содержащий RadioButton, в этом шаблоне вы можете привязать ваше свойство модели просмотра к RadioButton.GroupName
Ответ 4
IMHO, контроль, полученный из ItemsControl
, был бы самым чистым подходом.
Тогда вы, вероятно, переопределите
-
IsItemItsOwnContainerOverride()
с return item is RadioButton;
-
GetContainerForItemOverride()
до return
a new RadioButton()
для каждого элемента и
-
PrepareContainerForItemOverride()
, чтобы установить привязку ToggleButton.IsCheckedProperty
и ContentControl.ContentProperty
.
Хотя эти части являются только шаблоном кода, некоторые дополнительные усилия могут заключаться в реализации поведения клавиатуры.