将委托传递给在运行时创建的控件

时间:2011-01-20 22:10:19

标签: c# delegates

这更像是一个实施问题。 MainWindow有一个串行端口对象,它公开SendData(byte []数据)方法。 MainWindow还有一个选项卡控件,它在运行时通过外部XML文件填充。这些控件与串行端口交互,接收和发送数据。

对于发送,用户可以单击“发送”,它需要调用MainWindow.SendData()。问题是如何使控件调用MainWindow.SendData()而不引用MainWindow(我可以将SendData()移动到另一个类等)。

class MainWindow {
    SerialPort serialport;
    public MainWindow {
        // parse XML and add tabs to tabcontrol
        int tabcount = xmlreader.GetNodeCount(xpath);
        for (int i = 0; i<tabcount; i++) {
        tabitems[i] = new TabClass(tabname, ref tabControl);
    }
    public void SendData(byte[] data){
        serialport.Write(data,0,data.Length);
    }
}

class TabClass {
    TabItem tabitem;
    public TabClass(tabname, ref tabControl){
        tabitem = new TabItem();
        tabcontrol.Items.Add(tabitem);
        // add all controls (coming from xml)
        for (int i = 0; i < nrControls; i++) {
            // add control here, i.e. CommandControl
        }
    }
}    
class CommandControl {
    public Button_Click(){
        // Need to call SendData here!!
    }
}

首先想到的是将SendData委托传递给TabClass,然后让TabClass将委托传递给每个添加的自定义控件。我可以通过每个类构造函数,或者我可以使代理公开并让MainWindow直接写入它们。

我遇到的问题是我在每个用户控件和主TabControl中都创建并声明了委托。如果我决定更改实现,我将不得不在每个用户控件中更改声明。当然我仍然需要修改控件以包含新的实现,但我想避免在所有控件中重写声明。

问题:是否还有其他方法可以在不引用MainWindow的情况下从MainWindow公开SendData()委托?我想宣布一次并分享所有控件。

2 个答案:

答案 0 :(得分:1)

您可以使用Singleton类,也可以只使用静态类。

这必须与正好一个输出通道一致,这似乎是这种情况。

答案 1 :(得分:0)

你不需要委托。
用户帮助程序类。

class SerialWrapper {
    SerialPort serialport;  
    public void SendData(byte[] data){
        serialport.Write(data,0,data.Length);
    }
}

class MainWindow {
    SerialWrapper serialWrapper;
    public MainWindow {
        // parse XML and add tabs to tabcontrol
        int tabcount = xmlreader.GetNodeCount(xpath);
        for (int i = 0; i<tabcount; i++) {
        tabitems[i] = new TabClass(tabname, ref tabControl,serialWrapper);
    }
    public void SendData(byte[] data){
        serialWrapper.SendData(data);
    }
}

更新

class CommandControl {
    public CommandControl(SerialWrapper serialWrapper)
    {
          this.serialWrapper=serialWrapper;
    }

    public Button_Click(){
        serialWrapper.SendData();
    }
}