2013-02-25 70 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

相关问题