监听器类在表单上更改文本标签

时间:2015-10-28 11:36:47

标签: c# winforms

我在C#中有以下课程:

public class LeapEventListener : Listener
{
    public override void OnFrame(Controller controller)
    {
        Console.WriteLine("New Frame");
        // process frame data...
    }

    public override void OnInit(Controller controller)
    {
        Console.WriteLine("Initialized");
    }

    public override void OnConnect(Controller controller)
    {
        Console.WriteLine("Connected");
        //If using gestures, enable them:
        controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
    }

    //Not dispatched when running in debugger
    public override void OnDisconnect(Controller controller)
    {
        Console.WriteLine("Disconnected");
    }
}

并在表单加载时调用它:

controller.AddListener(listener);

我知道从类中更改标签不是一个好主意并且违反了某些编程范例但是如何更改标签文本而不是Console.WriteLine?

2 个答案:

答案 0 :(得分:2)

您需要将侦听器实现耦合到标签:

public class LeapEventListener : Listener
{
    public LeapEventListener(Label lbl)
    {
        if (lbl == null) {
            throw new ArgumentNullException("lbl");
        }

        this.lbl = lbl;
    }

    private readonly Label lbl;

    public override void OnFrame(Controller controller)
    {
        lbl.Text = "New Frame";
        // process frame data...
    }

    public override void OnInit(Controller controller)
    {
        lbl.Text = "Initialized";
    }

    public override void OnConnect(Controller controller)
    {
        lbl.Text = "Connected";
        //If using gestures, enable them:
        controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
    }

    //Not dispatched when running in debugger
    public override void OnDisconnect(Controller controller)
    {
        lbl.Text = "Disconnected";
    }
}

实例化侦听器时,从表单中传递标签。

编辑:我认为这是一个简洁的设计,因为Listener基类和你的形式是弱耦合的。这些类之间的唯一连接集中在这一个LeapEventListener类中,它充当桥梁。

如果您在此侦听器中执行更多操作(取决于"处理帧数据"的含义),您可能希望添加一个仅执行工作并调用抽象方法的附加继承层用于显示状态:

public abstract class LeapEventListener : Listener
{
    protected abstract void DisplayStatus(string message);

    public override void OnFrame(Controller controller)
    {
        DisplayStatus("New Frame");
        // process frame data...
    }

    public override void OnInit(Controller controller)
    {
        DisplayStatus("Initialized");
    }

    public override void OnConnect(Controller controller)
    {
        DisplayStatus("Connected");
        //If using gestures, enable them:
        controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
    }

    //Not dispatched when running in debugger
    public override void OnDisconnect(Controller controller)
    {
        DisplayStatus("Disconnected");
    }
}

public class LabelLeapEventListener : LeapEventListener
{
    public LabelLeapEventListener(Label lbl)
    {
        if (lbl == null) {
            throw new ArgumentNullException("lbl");
        }

        this.lbl = lbl;
    }

    private readonly Label lbl;

    protected override void DisplayStatus(string message)
    {
        lbl.Text = message;
    }
}

答案 1 :(得分:2)

这是“良好实践”方式之一。

首先,按如下方式修改您的课程

using

我所做的只是添加一个公共的readonly属性,一个私有方法来设置它和一个公共属性更改事件。

然后只需在表单加载中添加以下行(当然在创建public class LeapEventListener : Listener { private string status = string.Empty; public string Status { get { return status; } } public event EventHandler StatusChanged; private void SetStatus(string value) { if (value == null) value = string.Empty; status = value; var handler = StatusChanged; if (handler != null) handler(this, EventArgs.Empty); } public override void OnFrame(Controller controller) { SetStatus("New Frame"); // process frame data... } public override void OnInit(Controller controller) { SetStatus("Initialized"); } public override void OnConnect(Controller controller) { SetStatus("Connected"); //If using gestures, enable them: controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE); } //Not dispatched when running in debugger public override void OnDisconnect(Controller controller) { SetStatus("Disconnected"); } } 后):

listener

你已经完成了。

更新:根据您的评论:

(A)如果你想追加yourLabel.DataBindings.Add("Text", listener, "Status"); 。数据绑定仅适用于属性,因此在这种情况下,您只需附加一个事件处理程序,如下所示:

RichTextBox

(B)如果从非UI线程调用侦听器方法,那么忘记数据绑定,使用上面的事件处理程序,但方式略有不同:

listener.StatusChanged += (_sender, _e) =>
{
    yourRichTextBox.AppendText(listener.Status);
};