Winform и пользовательский контроль - C # - PullRequest
1 голос
/ 24 декабря 2009

У меня есть форма и пользовательский контроль. В UserControl есть меню, а в форме есть вкладка («Общие», «Еда», «Витамины» и т. Д.).

В UserControl у меня есть следующий код: (Имя формы - frmForm, имена вкладок в форме - tabGeneral, tabFood, tabVitamins)

  frmForm fm=new frmForm();
  fm.tabMain.Selected=tabVitamins;

Я вызываю эти строки из UserControl, чтобы захватить вкладку для выбора в форме, но она не выбирает вкладку витаминов.

Куда я иду не так? У меня есть спецификатор доступа как защищенный внутренний для вкладок в форме.

Пожалуйста, совет.

Спасибо, Karthick

Ответы [ 3 ]

7 голосов
/ 24 декабря 2009

Когда вы пишете new frmForm(), вы создаете совершенно новый экземпляр frmForm, который затем отбрасывается.

Чтобы получить экземпляр frmForm, который содержит ваш элемент управления, вызовите метод FindForm() и приведите к frmForm.

Например:

frmForm myForm = FindForm() as frmForm; 
if(myForm != null)
    myForm.tabMain.SelectedTab = myForm.tabVitamins;

Если элемент управления находится в какой-либо другой форме, этот код ничего не будет делать.


Кстати, венгерская нотация осуждается в .Net.
Ваша форма, вероятно, должна быть названа примерно как MainForm.

3 голосов
/ 24 декабря 2009

SLaks правильно указал на вашу фундаментальную ошибку и дал вам действительный пример способа, посредством вызова метода FindForm, чтобы получить форму, на которой расположен UserControl.

Вам может быть полезно помнить, что UserControl (и все элементы управления) также имеет свойство 'Parent', но, конечно, UserControl может быть помещен в другой элемент управления в форме (например, ваш UserControl может быть внутри панели формы): в этом случае родительский элемент UserControl будет элементом управления внутри формы (например, панелью), а не самой формой, но FindForm сделает все правильно, чтобы получить форму, в которой он находится. .

Однако вы вызываете метод каждый раз, когда используете FindForm, и «передовой опыт» предполагает, что вы хотите «вставить» ссылку на форму в UserControl во время выполнения, чтобы он всегда мог получить доступ к свойству Form легко, без вызова метода.

В вашем примере, на практическом уровне, это (вызов метода) может почти ничего не изменить в производительности, но, imho, когда вы доберетесь до места с WinForms и .NET, где у вас может быть UserControl, который будет нуждаться в доступе к родительской форме очень часто, это окупится, и это лучший способ структурировать ваш код в долгосрочной перспективе для обслуживания.

Уэс показал вам, как вы можете «встроить» (внедрить) форму размещения UserControl: использование перегруженного конструктора для UserControl. Но для этого необходимо изменить файл Designer.cs в стандартных WinForms, и я настоятельно рекомендую вам не делать этого, даже если он будет работать. В частности, если вы просто «встали на ноги» в .NET, я настоятельно рекомендую вам не изменять его или что-либо связанное с конструктором формы и его внутренним вызовом: InitializeComponent ();

Кроме того, по мере развития WinForms вы столкнетесь со многими ситуациями, когда вам нужно, чтобы экземпляры «объектов» (элемент управления, форма, экземпляр класса) содержали ссылки на другие экземпляры «объектов». .

Если вы сможете понять и использовать одно простое использование «инъекции» здесь, вы добьетесь прогресса, чтобы в будущем подготовиться к более сложному программированию .Net.

Другим способом является помещение Public Property в UserControl, который можно установить в коде из MainForm. В пользовательском контроле что-то вроде:

private frmForm ParentForm;

public frmForm UCParentForm
{
    set { ParentForm = value; }
}

Итак, в коде вашей основной формы, возможно, в событии Load, например:

private void frmForm_Load(object sender, EventArgs e)
{
    TheUserControl.UCParentForm = this;
}

или когда вам нужно, вы устанавливаете свойство UserControl 'ParentForm один раз. Таким образом, вы устранили использование метода FindForm ().

В этом случае, если вы хотите получить доступ только к определенному элементу управления в родительской форме UserControl, например, к TabControl, вы можете подумать, что вы хотите задать свойство, которое вы устанавливаете, типа TabControl, а не Form: тот же метод кодирования показанное выше может использоваться в UserControl:

private TabControl mainFormTabControl;

public TabControl MainFormTabControl
{
    set { mainFormTabControl = value; }
}

imho, это когда вы динамически создаете UserControls во время выполнения, и использование перегруженного конструктора, как предполагает Уэс, является лучшей стратегией. И использование перегруженных конструкторов имеет много, много других применений в .NET, в которые вы попадете.

удачи!

1 голос
/ 24 декабря 2009

Вы не должны создавать новый frmForm () внутри пользовательского элемента управления. Вы можете передать ссылку на frmForm в пользовательский элемент управления.

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

private frmForm fm;

public YourUserControl(frmForm fm)
{
    this.fm = fm;
}

Тогда вы могли бы использовать.

fm.tabMain.Selected=tabVitamins;

Это помогает?

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