Заменить метод ShowDialog, чтобы вернуть конкретные данные?

Я использую форму TopMost, которая, когда она показана, просто ждет, когда OnMouseDown выберет область на экране, и при событии OnMouseUp я закрываю форму, тогда я собираюсь вернуть прямоугольник, который содержит выбранную область после OnMouseUp событие... когда форма закрывается с помощью вызова ShowDialog.

Что-то вроде этого:

Dim Rect As Rectangle = MyForm.ShowDialog

Поэтому я подумал, что переопределение / замена должным образом функции ShowDialog для возврата другого DataType может быть наиболее эффективным способом, но я не знал, как это сделать правильно, мне нужен пример кода.

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

1 ответ

Решение

Нет, ты не можешь этого сделать. Когда вы переопределяете метод в производном классе, вы не можете изменить тип возвращаемого им значения. В более технических терминах вы не можете изменить сигнатуру метода, как определено в базовом классе.

Что вы можете сделать, это вернуть более конкретный производный тип, но это не поможет в этом случае. Вы не можете наследовать от DialogResult и это не будет служить какой-либо цели, даже если вы могли бы.

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

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

  1. Вы не можете определить, как пользователь закрыл диалог. Стандартный диалог будет иметь кнопку подтверждения ("ОК"/"Да") и кнопку отмены ("Отмена"/"Закрыть"/"Нет"). Вы хотите выполнить действие, только если пользователь нажал кнопку подтверждения. Если они нажали кнопку отмены, вы хотите выручить.

    Если вы возвращаете другой тип из ShowDialogвам нужно будет найти способ сообщить, был ли диалог отменен. Что вы собираетесь вернуть в виде прямоугольника (или чего-то еще), если диалог был отменен?

    Вы бы в конечном итоге сделать какую-то ерунду, как вернуть Nullable<Rectangle>и ты ничуть не лучше, чем там, где ты начал.

  2. Если вы используете его как пример кода, показанный в вопросе, вы забудете позвонить Dispose метод в вашей диалоговой форме и утечки ресурсов.

    Это важный момент, который забывают многие программисты WinForms. Когда вы закрываете нормальную, немодальную форму, Dispose метод вызывается автоматически. Но он не вызывается автоматически для модальных диалогов, показанных с помощью ShowDialog метод. В этом случае вы должны позвонить Dispose себя вручную. (Почему, вы можете спросить? Просто, потому что после закрытия диалогового окна вы почти всегда хотите прочитать значения из его свойств, чего нельзя сделать, если он был удален.)

    Таким образом, стандартная идиома для показа модального диалога - вот эта; Я настоятельно рекомендую вам использовать его:

    Using myDialog As New MyDialogForm
        If (myDialog.ShowDialog() = DialogResult.OK)
            ' Do whatever it is you want to do, including
            ' reading the values of properties of myDialog.
            '
            ' For example:
            Dim rect As Rectangle = myDialog.SelectedRectangle
            ' ...
        End If
    End Using
    

    С Using заявление, вам не нужно называть Dispose метод, он обрабатывается автоматически, даже если выдается исключение. В этом нет ничего необычного и не должно быть неожиданным. Using заявления, как вы имеете дело с любым ресурсом, который реализует IDisposable, Модальные диалоги не являются исключением.

  3. Это нестандартная идиома, которая может запутать будущих программистов. Люди ожидают, что это вернет DialogResult значение. Даже если вы не заботитесь о других людях, если вы чем-то похожи на меня, когда вы вернетесь, чтобы посмотреть на код, который вы написали через 3 месяца, возможно, это был первый раз, когда вы его видели.

TL; DR: Нет, просто добавьте обычное старое свойство к производному классу Form, который вы показываете в качестве модального диалога.

Другие вопросы по тегам