2013-02-25 68 views
0

我有一個班級和一個表格。該類旨在在引發事件時執行一些過程,並將值返回給窗體以僅顯示。我有種問題傳回價值形式。舉例來說,我有這樣的代碼在print類:將值從另一個類傳遞給表單中的文本框?

public class PrintClass : Form1 
{ 

    public void printEventHandler(object sender, EventArgs e) 
    { 

     string text = "Process Completed"; 
     append_Tbox(text); 

    } 

} 

,並在Form1的方法來顯示文本:

public void append_Tbox(string s) 
    { 

     TboxPrint.AppendText(s); 
    } 

然而,什麼也不顯示。我相信有錯,但我無法弄清楚。 什麼是從類傳遞值形式的最快方式?

+0

從你提供的代碼看起來像append_Tbox函數是在同一個類中。我是否正確 – Vikram 2013-02-25 05:24:04

+0

@Vikram,類'PrintClass'繼承'form1',這就是爲什麼我可以直接調用方法。 – Liban 2013-02-25 05:26:25

+0

@ Liban-你不能訪問類的TxtBox,因爲兩個控件都是私有的,請參閱Designer.cs – 2013-02-25 05:37:30

回答

1

首先,你的處理類不應該延伸Form1。這給你一種錯覺,即你可以訪問你現有表單的方法,但這並不是按照你的想法進行的。當你這樣做時,你正在創建一個全新的表單,而不是顯示它。這種形式有它自己的所有實例字段,所以你不能訪問你主表單的控件。即使這會起作用(它不會),但它不是一個設計良好的解決方案。

這樣做的正確方法實際上要容易得多。你只需要在你的其他類從它的方法返回一個值:

public class PrintClass 
{ 
    public string DoWork() 
    { 
     Thread.Sleep(2000);//placeholder for real work. 
     return "Process Completed"; 
    } 
} 

現在你的主要形式,可以直接調用該方法和返回值追加到一個文本框。

一旦你這樣做,你將會有一個完全獨立的問題。如果你在UI線程中完成工作,你將在工作進行時阻止該UI線程,阻止表單被重新繪製或處理任何其他事件。您需要在後臺線程中完成這項工作,然後編組回UI線程以更新UI的結果。有許多這樣做的方法,但是如果你有C#5.0中await是迄今爲止最簡單的:

public class Form1 : Form 
{ 
    private void SomeEventHandler(object sender, EventArgs args) 
    { 
     string result = await Task.Run(()=>new PrintClass().DoWork()); 
     TboxPrint.AppendText(result); 
    } 
} 

如果你需要一個C#4.0解決方案,您可以使用ContinueWith,這或多或少是什麼上面的內容將被翻譯成,但它不像語法清晰。

public class Form1 : Form 
{ 
    private void SomeEventHandler(object sender, EventArgs args) 
    { 
     Task.Factory.StartNew(()=>new PrintClass().DoWork()) 
      .ContinueWith(t => TboxPrint.AppendText(t.Result) 
       , CancellationToken.None 
       , TaskContinuationOptions.None 
       , TaskScheduler.FromCurrentSynchronizationContext()); 
    } 
} 
+0

,它正在處理哪個事件?順便說一句,認爲在c#4.0中沒有'await' – Liban 2013-02-25 07:00:35

+0

@Liban無論你希望這項工作做了什麼事情,這並不重要。從它的聲音中,只有一件事正在處理。你是對的,在C#4.0中沒有'await',這就是爲什麼我說你可以做到這一點,如果你使用C#5.0。 – Servy 2013-02-25 07:02:11

+0

是否有任何替代'Task.Run'?因爲它給出了一個錯誤:''System.Threading.Tasks.Task'不包含'Run'的定義。也許它不存在C#4.0。我試圖尋找其他的選擇,但我不能。 – Liban 2013-02-26 04:24:12

0

我在主窗體創建委託

public delegate void LoginDelegate(string s); 

public partial class AirLineReservationMDI : Form 
    { 
     LoginDelegate loginAirLineDelegate; 

    } 

loginAirLineDelegate = new LoginDelegate(DisableToolStripMenuItems); 


public void DisableToolStripMenuItems(string s) 
     { 
      this.viewToolStripMenuItem.Visible = true; 
      this.bookingToolStripMenuItem.Visible = true; 
      this.existingUserToolStripMenuItem.Visible = false; 
      this.newUserToolStripMenuItem.Visible = false; 
      this.toolStripStatusUserID.Text = "USerID :- "+s;    
      this.LoginUserId = s; 
     } 
在另一類

,(我已通過delagete對象這一類) 我解僱了代表

logDelegate(textBoxUserName.Text); 
+0

這是行不通的,因爲委託人仍然會對錶單的不正確實例採取行動。 – Servy 2013-02-25 06:51:04

+0

Servy-我已經使用Delagete來執行此活動。他需要設置另一個TxtValue類,更好和簡單的選項是Deleagte,我們使用委託來實現這個功能。 – 2013-02-25 06:57:19

+0

你還沒有解決我的評論;你剛剛陳述了幾個無關的事實,這些事實並不意味着什麼。在這種情況下,使用委託與直接調用方法沒有區別,這不適用於他。這個答案沒有幫助,也沒有解決OP所面臨的根本問題。 – Servy 2013-02-25 07:00:33

0

我用Action<T>委託來解決問題。這裏是代碼,它工作正常。

class PrintClass 
{ 
    public Action<string> DisplayDelegate; 


    public void printEventHandler(object sender, EventArgs e) 
    { 
     string text = "Event Handled, and text value is passed"; 

     var copy = DisplayDelegate; 

     if (copy != null) 
     { 
      copy(text); 
     } 
    } 

} 

和`Form1.cs的:

private void Form1_Load(object sender, EventArgs e) 
    { 
     PrintClass p = new PrintClass(); 
     BtnPrint.Click += p.printEventHandler; 

     //subscrite the displayevent method to action delegate 
     p.DisplayDelegate += DisplayEvent; 

    } 


    public void DisplayEvent(string s) 
    { 

     Invoke(new Action(() => TboxPrint.AppendText(s))); 
    } 

所以文本 '事件處理,文本值傳遞' 顯示在文本框。

我不知道這是否是有效的方法。 謝謝你們。

+0

您的*實際*打印事件處理程序需要很長時間才能運行?這個並沒有真正做任何事情,但是如果真實事件將花費大量時間進行處理,那麼這項工作將阻止UI線程,這是一個問題。另外,如果你確實使用了這個,你應該使用'event',而不是原始代理。只需在'PrintClass'中使用'公共事件動作 DisplayDelegate;'。你也應該把它稱爲更像'PrintCompleted'而不是'DisplayDelegate',因爲它更恰當地表明它是什麼。 – Servy 2013-02-27 14:47:54

+0

你是對的。它阻止了UI線程。謝謝澄清。這真的幫助我明白了這一點。 – Liban 2013-02-28 02:41:36

相關問題