2013-02-08 2 views
1

Мне нужно сделать классы в моей программе, чтобы начать цепочку событий, чтобы написать текст в текстовом поле. Я знаю, что классы не должны знать о форме. как это сделать? учтите, что я установлю класс на другой поток.Запись в текстовом поле из класса anoter (на другой поток)

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

* обновление: * вы все неправильно поняли меня - я говорил о событиях, не связанных с запрограммированием. все, что мне нужно, это добавить текст в текстовое поле из другого класса. Я добавил «цепочку событий», чтобы определить ее из вопросов simila, в которых они пытались правильно изменить текст из класса. Прости.

ответ

2

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

  1. Класс имеет событие.
  2. Форма запускает и создает класс.
  3. Форма назначает обработчик событию в классе.
  4. Класс делает все, что ему нужно, пока не достигнет точки, где ему необходимо связаться с формой.
  5. Класс вызывает событие.
  6. Обработчик в форме запускается и изменяется текстовое поле.

Так в коде класса вам нужно добавить несколько определений:

public delegate void FinishedEventHandler(object sender, string ValueToReturn); 
public event FinishedEventHandler Finished; 

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

Теперь в функцию, которая делает то, что обработка класса делает нам нужно поднять событие, когда соответствующее:

void DoSomething() 
{ 
    . 
    . 
    . 
    if(Finished!=null) Finished(this, "some value"); 
} 

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

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

private void FinishedEventHandler(object sender, string ValueToReturn) 
{ 
    TextBox1.Text = ValueToReturn; 
} 

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

MyClass.Finished += FinishedEventHandler; 
MyClass.DoSomething(); 

Вот более подробный учебник:

http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx

+1

Фактически все это может быть выражено в трех строках кода, что, безусловно, может быть сделано в рамках короткого ответа. Шаг 6 не имеет никакого кода, связанного с ним, а шаги 2 и 4 - это вещи, которые реально можно ожидать, что ОП будет самостоятельно определять; они не должны быть в вашем ответе. Это действительно хороший подход к использованию. – Servy

+1

Одна вещь, о которой не упоминает Система, заключается в том, что вы выполняете перекрестную связь, вам нужно будет «вызывать» внутри обработчика события в форме. –

+0

1) При определении события нет необходимости определять свой собственный тип делегата. Просто используйте 'Action' /' Func', или если вы действительно считаете себя обязанным использовать обработчик на основе событий, вы можете использовать «EventHandler ». 2) для назначения обработчика события вы можете использовать лямбда, что намного эффективнее для этих реальных небольших событий, хотя именованный метод всегда можно использовать для нетривиальных обработчиков. – Servy

4

Есть два возможных варианта здесь:

«Другой класс» нужно обновить текстовое поле, как только это «сделано» с его работой. Если это так, то он никогда не должен знать о форме, любом текстовом поле, интерфейсе, ничего. Он должен просто вернуть значение и позволить форме использовать это возвращаемое значение, чтобы установить текстовое поле, или сделать что угодно.

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

Если информация не выполняется, когда задача выполнена, но вместо этого через периодические интервалы, то вы можете использовать класс Progress с интерфейсом IProgress.

Имейте Form создать экземпляр: Progress<string> progress = new Progress<string>();. иметь форму, прикрепляющую обработчик события для этого экземпляра. Обратите внимание, что экземпляр Progress «захватит» текущий контекст синхронизации, который является причудливым способом сказать, что он работает в потоке пользовательского интерфейса. Это можно сделать так:

progress.ProgressChanged += (_, data) => textBox1.Text = data; 

Тогда просто другой класс принять IProgress<string> экземпляр и периодически вызывать:

progress.Report(someString); 

Если вам нужна предварительная 4.5 реализации Progress и IProgress, здесь реализация, которая будет компилироваться и выполняться в .NET 3.5+:

public interface IProgress<T> 
{ 
    void Report(T data); 
} 

public class Progress<T> : IProgress<T> 
{ 
    SynchronizationContext context; 
    public Progress() 
    { 
     context = SynchronizationContext.Current 
      ?? new SynchronizationContext(); 
    } 

    public Progress(Action<T> action) 
     : this() 
    { 
     ProgressReported += action; 
    } 

    public event Action<T> ProgressReported; 

    void IProgress<T>.Report(T data) 
    { 
     var action = ProgressReported; 
     if (action != null) 
     { 
      context.Post(arg => action((T)arg), data); 
     } 
    } 
} 
+1

Обратите внимание, что [IProgress] (http://msdn.microsoft.com/en-us/library/hh138298.aspx) является новичком в .NET 4.5, поэтому, если вы настроите таргетинг на более раннюю структуру, он не будет доступен. –

+0

@ScottChamberlain Правда, хотя для этого не требуется никаких новых функций языка; вы можете написать свой собственный класс/интерфейс 'Progress' всего за несколько десятков строк кода. – Servy

+0

Очень правдиво, я просто не хотел, чтобы ОП попадала в ловушку, если он не мог найти интерфейс. –

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