Открытие winform из пользовательского элемента управления и передача значений обратно в usercontrol - PullRequest
1 голос
/ 04 февраля 2010

Мне было интересно, возможно ли, чтобы пользовательский элемент управления открыл winform, которая позволяет пользователю выбирать параметры на нем, а затем, когда он закрывает форму - выбранные параметры / значения возвращаются пользовательскому элементу управления?

Ответы [ 3 ]

6 голосов
/ 04 февраля 2010

Почему бы не создать некоторые публичные свойства в диалоговой форме и получить к ним доступ из UserControl после закрытия диалога?

public class OptionsForm : Form
{
    // ...

    public string Option1 { get; set; }
    public bool Option2 { get; set; }
}

А затем, в UserControl:

public void ShowOptionsForm()
{
    using (var form = new OptionsForm())
    {
        if (form.ShowDialog() == DialogResult.OK)
        {
            var option1Value = form.Option1;
            var option2Value = form.Option2;

            // use option values...
        }
    }
}
4 голосов
/ 04 февраля 2010

Пожалуйста, рассмотрите этот ответ как «расширенный комментарий» к уже принятому ответу Стива Грейтрекса: он слишком длинный для комментария, и я хочу продемонстрировать несколько вариантов, добавить несколько «ароматов» на вкус.Это вовсе не «критика» ответа Стива, который, imho, ударил «яблочко».

Предположения: если бы я читал вопрос ранее, я бы запросил ОП через комментарий к каждому изэти пункты:

  1. ОП не указывал, должна ли форма, которая будет "показана", отображаться в модальном порядке или нет.

  2. ОП не указывал, должна ли форма создаваться заново каждый раз, когда ее показывают, или один ее экземпляр должен создаваться и использоваться повторно.

  3. ОП написал «открыть winform, которая позволяет пользователю выбирать параметры на ней ... snip ...« возвращаемые параметры / значения возвращаются »: код Стива не показывает, как именно свойствавыставлены как Public, но я собираюсь предположить, что OP, вероятно, имел в виду, что пользователь взаимодействовал с некоторыми элементами управления в показанной форме, и что «опции / значения», на которые он ссылается, являются свойствами элементов управления в форме: как конечный пользователь, набирающий некоторый текст в TextBox, или выбранные индексы в ListBox с его SelectionMode, установленным, чтобы разрешить один из двух вариантов множественного выбора.

  4. OP не делаетСкажите, если желательно, чтобы Форма (если она использовалась неоднократно) сохраняла результаты последних взаимодействий конечного пользователя с элементами управления в Форме, как описано выше.

  5. OP ничего не говорит о том, имеет ли форма, показанная в UserControl, свойство Parent, установленное для какого-либо другого допустимого контейнера: я предполагаю, что они означают, что форма будет отображаться «без родителя».

Комментарии:

  1. , если OP предполагал, что Форма будет отображаться модально : для того, чтобы код Стива работал,Элемент управления ControlBox формы должен быть исключен как опция, а на форму была помещена кнопка, свойство «DialogResult» которой установлено в «OK», а событие «Click» закрыло форму: без соблюдения этих условий результат ShowDialog в Steve'sкод никогда не будет возвращать «ОК», а значения свойств никогда не будут установлены.Примечание: закрытие формы через ControlBox вернет DialogResult «Cancel».

  2. повторное использование показанной формы : если мы предполагаем, что форма будетвероятно, будет использоваться повторно, тогда почему бы не создать его один раз, а затем «Показать и закрыть», если необходимо?Давайте рассмотрим возможность того, что могут быть веские причины выставлять созданную Форму как открытый элемент UserControl.

Рассмотрим следующую альтернативную идею : попытка представитьрешение, настолько «отличное», насколько это возможно от решения Стива: просто для демонстрации, изучения вариантов.

Наша «показанная форма» будет иметь TextBox и ListBox, который допускает множественный выбор: наша цель - показать текств TextBox и текущем выборе индексов в ListBox.

  1. Форма имеет ControlBox: не требует закрытия кнопки, как описано выше.

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

  3. свойства Public, которые должны быть установлены, должны основываться начтение текущего состояния элементов управления в отображаемой форме.

  4. Форма создается один раз и отображается как общедоступная: из-за этого «побочным эффектом» является то, что когдаформа будет отображаться повторно, в ней будут сохранены предыдущие результаты того, что выбрал пользователь, и т. д. Конечно, есть другие способы, которыми вы могли бы легко контролировать это в своем коде, чтобы снова сделать один или все элементы управления «девственными».

в «показанной форме» , которую мы назвали 'DataEntryForm:

Так же, как показывает Стив, мы определяем открытые свойства для показа;

public string TextEntered { get; set; }

public ListBox.SelectedIndexCollection LBSelection { get; set; }

В событии закрытия формы мы обновляем свойства в зависимости от состояния элементов управления:

private void DataEntryForm_FormClosing(object sender, FormClosingEventArgs e)
{
    TextEntered = textBox1.Text;
    LBSelection = listBox1.SelectedIndices;
}

в UserControl мы создаем открытое свойство типа 'DataEntryform (причина, по которой нужно объяснить)

public DataEntryForm theDataEntryForm { get; set; }

Мы создаем экземпляр DataEntryForm в событии загрузки UserControl и присваиваем его общедоступному свойству

private void UserControl1_Load(object sender, EventArgs e)
{
    theDataEntryForm = new DataEntryForm();
}

На этом этапе мы оставим это на усмотрение ОП (и вашего), чтобы представить, когда показан экземпляр DataEntryForm. Но, конечно, мы хотим продемонстрировать, как вы будете обращаться к свойствам после закрытия формы: поэтому мы помещаем кнопку в элемент управления UserControl:

    private void button2_Click(object sender, EventArgs e)
    {
        Console.WriteLine(theDataEntryForm.TextEntered);
        Console.WriteLine(theDataEntryForm.LBSelection.ToString());
    }

Примечание: мы не делали «причудливый» анализ выбранных индексов ListBox: но мы могли бы записать, было ли оно нулевым, или сколько элементов было выбрано и т. Д.

Также: мы не занимались вопросом о том, что если ОП захочет предпринять какое-либо действие в момент закрытия «показанной формы»: это так просто: вы просто подписываетесь на событие FormClosed формы в UserControl и делайте то, что вам нужно, в своем коде обработчика событий.

Наконец, мы подходим к вопросу о том, зачем делать Public Property типа 'DataEntryForm:

Хорошо, просто учтите, что, выставив эту «показанную Форму» через Открытое Свойство в UserControl: мы позволяем потенциальным контейнерам (возможно, Форме) экземпляров UserControl также иметь доступ к значениям Элементов управления на " Показанная форма "... которая может быть ценной, может спасти нас от некоторого дублирования свойств.

Итак, если UserControl1 находится в Form1, а Form1 хочет знать значение Text для TextBox в «показанной форме»: к нему можно получить доступ так:

this.userControl11.theDataEntryForm.TextEntered

Редактировать: мой друг написал мне, чтобы выразить свое мнение о том, что предоставление контейнеру "высокого уровня" прямого доступа к "компоненту", встроенному в UserControl, было "нарушением" хорошей практики OOD и нарушает инкапсуляцию: он выпустил меня трогательное нарушение билета :) Итак, имейте в виду его предупреждение. С его точки зрения, свойства должны дублироваться в UserControl с разными именами, и только те свойства UserControls должны быть доступны для контейнера UserControl. Я склонен видеть здесь «UserContro / Form» как один «составной объект», который, поскольку форма используется исключительно пользовательской формой, не оправдывает дублирование свойств / Edit

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

0 голосов
/ 04 февраля 2010

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

этот код отправляется туда, где вы строите свой элемент управления и формируете

MyUserControl ctrl = new MyUserControl();
Action<typeYouPassBack> callBack = myUserControl.FormCallBack;
MyOptionForm form = new MyOptionForm(callBack);

тогда класс формы должен выглядеть примерно так: (важная часть - аргумент действия)

class MyOptionForm : Form
{
  private readonly Action<typeYouPassBack> _callBack;
  public MyOptionForm(Action<typeYouPassBack> callBack)
  {
    _callBack = callBack;
    Close += form_Close;
  }

  privatre void form_close(object sender, EventARgs e)
  {
     typeYouPassBack postBackData = //populate the postback data
     _callBack(postBackData);
  }
}

тип Action - это просто делегат с подписью void f (T arg). В приведенном выше коде ожидается, что пользовательский элемент управления будет иметь метод с именем «FormCallBack», который, конечно, может быть назван как угодно, если вы используете правильное имя при назначении его переменной «обратный вызов»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...