Как избежать автоматической группировки контейнера в Windows Forms - PullRequest
7 голосов
/ 23 февраля 2009

Фон

В .NET Windows Forms (2.0) переключатели автоматически группируются по элементу управления контейнера, будь то Form, Panel или GroupBox.

Это означает, что при выборе одной радиокнопки все остальные радиокнопки в том же контейнере автоматически переводятся в непроверенное состояние.

Теперь рассмотрим следующий макет формы:

MUST HAVE  NICE TO HAVE  DESCRIPTION
---------  ------------  -----------------------------------------------
   [ ]          [ ]      The gizmo works
   [ ]          [ ]      The gizmo works beautifully
   [ ]          [ ]      The gizmo works amazingly and makes you breakfast
   [ ]          [ ]      The gizmo comes with a pony
  • Каждый '[ ]' является переключателем.
  • Пользователю предлагается выбрать обязательный ответ в первом столбце и необязательный (требуемый, наилучший ответ) в столбце 2.

Как видите, переключатели должны быть сгруппированы по столбцам: выбор одного из переключателей должен очистить остальную часть столбца, но не должен влиять на другой столбец.

Проблема

В основном проблема в том, что это динамически генерируемая форма.

  • Число строк в макете является динамическим и загружается из настраиваемого определения формы.
  • Текст описания неизвестен до тех пор, пока время выполнения и его длина сильно не изменятся (у некоторых может быть всего пара слов, а у других - дюжина строк).
  • Макет не может быть изменен. Это происходит из-за знакомства (нетехнических) пользователей с бумажной версией этой формы, которая использовалась в течение многих лет. Эта форма также будет напечатана, и даже если я изменю систему ввода в своей форме, это будет означать кодирование другой версии для печати со «старым» макетом.

То, что я пробовал и не работало

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

Но проблемы с макетом, связанные с горизонтальным выравниванием переключателей и их текста, просто убивают меня. Размер текста неизвестен до времени выполнения, и текстовые строки могут переноситься (иногда несколько раз для каждого элемента). Иногда он выравнивается правильно, иногда нет. Я собираюсь начать отлаживать это, но я думаю, что, может быть, лучше изменить эту трехпанельную реализацию.

Что я пытаюсь сделать

Я хотел бы изменить макет, используя TableLayoutPanel с тремя столбцами, чтобы упростить проблемы, связанные с выравниванием, но это означает, что я не могу использовать "функцию" автоматической группировки радиокнопок.

EDIT:

Как предложил Джерри, другой вариант макета состоит в том, чтобы каждая строка была реализована как пользовательский элемент управления и использовать панель макета потока.

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

Мне нужно получить вертикальные группы переключателей, несмотря на использование горизонтальных пользовательских элементов управления

/ EDIT

Что я пытаюсь спросить

Мне нужны указатели и предложения о том, как вручную управлять группировкой переключателей. Я действительно не возражаю против подкласса класса RadioButton, если это необходимо.

В частности, существует ли какой-либо «канонический» или известный способ подкласса «RadioButton» или весь путь до API Win32, чтобы каждый раз проверять элемент управления (с помощью мыши, клавиатуры Enter, пробела и любой другой способ, которым я не мог знать об их выборе) Я могу перехватить событие и вручную обновить состояние любого другого элемента управления в моей форме и таким образом, чтобы функция автоматической группировки, как известно, была деактивирована? Я боюсь, что реализация также связана с контейнером, и я мог бы также быть вынужден создать подкласс Panel?.

Как работает групповое «волшебство» в Windows Forms?

Каждое найденное мною решение, которое реализует пользовательские группы радиокнопок или «списки радиокнопок», каким-то образом основано на использовании контейнера для группы. Можно ли избежать контейнеров? Если да, то как?

Ответы [ 2 ]

6 голосов
/ 23 февраля 2009

A временное решение (читай: грязный хак ) Я обнаружил, что я помещаю каждый и каждый переключатель в свою маленькую панель. Так что между ними не происходит никакой группировки. Я слушаю каждую кнопку checked событий и соответственно обновляю соответствующие.

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

(Хорошо, извините за ответ на мой собственный вопрос. Вы знаете, что, когда вы тратите время, чтобы что-то объяснить, вы начинаете видеть проблему в другом свете.)

1 голос
/ 23 февраля 2009

Я бы выбрал простое и понятное решение. Например, пользовательский элемент управления, представляющий одну строку (например, две радиокнопки и метку).

РЕДАКТИРОВАТЬ: ОК, я думаю, я понимаю ваше требование сейчас. Разве у вас нет двух наборов радиокнопок: в столбце A и в столбце B?

Когда ваша форма нарисована, добавьте их в два списка или что-то еще и привяжите их к двум отдельным событиям: columnARBChecked, columnBRBChecked. Когда происходит одно из событий, вы можете вызвать некоторую логику для проверки / снятия отметки с остальных радиокнопок, если хотите.

...