2010-11-04 1 views
3

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

У меня есть форма для окон, Form1, с текстовым полем: tbx_Log.

В другом классе в том же проекте я хочу что-то написать в текстовом поле журнала, но я не могу ссылаться на tbx_Log в этом классе. Как я могу это достичь?

ответ

4

Доступ к объектам внутри других экземпляров класса (объектов) является плохим стилем и нарушением инкапсуляции данных. Добавить метод Form1:

public void SetLogText(String text) 
{ 
    tbx_Log.Text = text; 
} 

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

+0

Итак, должен ли я создать объект моей формы, такой как это окно ReconcilerConsoleWindow = new ReconcilerConsoleWindow(); в каждом классе для доступа к SetLogText? – xbonez

+0

Нет, объекты являются экземплярами класса и создаются с новым. Если вы сделаете это так, как вы говорите, вы получите «n» разные объекты класса «ReconcilerConsoleWindow». В большинстве случаев вам нужно будет предоставить классы с помощью 'ReconcilerConsoleWindow' с свойством для установки' ReconcilerConsoleWindow'. Таким образом вы можете установить один и тот же объект 'ReconcilerConsoleWindow' для нескольких объектов, используя его. – jdehaan

2

Вам либо нужно сделать текстовое поле общедоступным (не рекомендуется), либо добавить общедоступный метод в класс формы, который будет писать строку в текстовое поле (лучше).

public class Form1 
{ 
    protected Textbox tbx_Log; 
    public void Log(string str) 
    { 
     tbx_Log.Text += str + Environment.NewLine; 
    } 
} 

public class Program 
{ 
    private void DoStuff() 
    { 
     Form1 myForm = new Form1(); 
     //Make form visible, etc... 
     myForm.Log("Test Log"); 
    } 
} 
+0

Если бы я хотел войти в систему из нескольких классов, кроме программы, должен ли я инициализировать объект Form1 в каждом из этих классов? – xbonez

+0

Нет, но если вы идете по маршруту метода, вам, по крайней мере, нужно будет передать ссылку на класс Form1 ко всем другим классам, которые вы создаете. Вы должны только вызвать конструктор для формы один раз, поскольку я предполагаю, что вы будете смотреть только на одну форму. – jafesler

1

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

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

0

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

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

public void SetText(string text) 
{ 
    // InvokeRequired required compares the thread ID of the 
    // calling thread to the thread ID of the creating thread. 
    // If these threads are different, it returns true. 
    if (this.textBox1.InvokeRequired) 
    {  
     SetTextCallback d = new SetTextCallback(SetText); 
     this.Invoke(d, new object[] { text }); 
    } 
    else 
    { 
     this.tbx_Log.Text = text; 
    } 
} 

Для полной выборки и объяснения потокобезопасных звонков на WinForms проверить MSDN, который также показывает, как использовать BackgroundWorker для достижения потокобезопасности, которая является предпочтительным способом сделать это.

2

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

Смежные вопросы