2015-10-28 2 views
1

У меня есть следующий класс в C#:Слушатель Class изменение текстовой метки на моей форме

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?

+0

Какой тип 'Контроллер' (какое пространство имен)? Кажется, это не '' System.Web.Mvc.Controller'' (https://msdn.microsoft.com/en-us/library/system.web.mvc.controller%28v=vs.118%29 .aspx), поскольку у этого нет метода «EnableGesture» или «AddListener». –

+0

Leap type, is about leapmotion.com –

+0

Кроме того, что подразумевается под «заменой метки из класса»? Я не понимаю эту фразу. Поскольку C# объектно-ориентированный, вы практически всегда находитесь в классе с тем, что вы делаете. Следовательно, я понятия не имею, как вы могли бы «изменить ярлык» без класса, или почему это было бы лучше, чем делать это «из класса». –

ответ

2

Вот один из способов «хорошей практики».

Во-первых, изменить ваш класс следующим образом

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 создается):

yourLabel.DataBindings.Add("Text", listener, "Status"); 

, и вы сделали.

UPDATE: В соответствии с вами комментарии:

(A) Если вы хотите добавить к RichTextBox. Привязка данные работают только со свойствами, так что в этом случае вы можете просто прикрепить обработчик события, например:

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

(B) Если методы прослушивателя называется из не потока пользовательского интерфейса, а затем забыть о связывании данных, использование обработчик событий, как описано выше, но несколько иным образом:

Action onStatusChanged =() => 
{ 
    // Whatever UI element you want to update 
    yourLabel.Text = listener.Status; 
    yourRichTextBox.AppendText(listener.Status); 
}; 
listener.StatusChanged += (_sender, _e) => 
{ 
    if (InvokeRequired) 
     Invoke(onStatusChanged); 
    else 
     onStatusChanged(); 
}; 
+0

Спасибо! Прекрасно работает! Но почему «RichTextBox1.DataBindings.Add» («AppendText», прослушиватель, «Статус»); 'не работает? –

+0

@IonVasile Поскольку метод «AppendText» - это метод, а привязка данных работает только со свойствами. –

+0

Я вижу, поэтому я не могу добавить в richtextbox, что делает слушатель? –

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"; 
    } 
} 

При вызове слушателя, передать метку от вашей формы.

EDIT: Я бы сказал, что это чистый дизайн, потому что базовый класс 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; 
    } 
} 
+0

Отлично работает, но это хорошая практика? –

+1

@IonVasile. Вы также имеете возможность вызвать метод в форме и затем отделить его от события на интерфейсе, который реализует форма, а затем назначить форму для реализации этого интерфейса. Это позволит вам назначить слушателю представление/представление сети/просмотр ui слушателю. Какая может быть отличная функция - или в зависимости от вашего проекта - пустая трата времени, в результате чего ваше «Go To Definition» ищет посадку в интерфейсе каждый раз без реальной выгоды. –

+0

@IonVasile: Я обновил свой ответ с дальнейшими мыслями по этому поводу. –

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