7

I want a button that when it's pushed a new string is shown in the textboxes.

What am I doing wrong?

Can someone enlighten me? Why doesn't this code work?

namespace WindowsFormsApplication1 { public partial class Form1 : Form { public event Startdelegate StartEvent; myButton button; newTb[] tb; public Form1() { InitializeComponent(); button = new myButton(); button.Parent = this; button.Location = new Point(120, 0); button.Text = "click on me!!!"; tb = new newTb[8]; for (int i = 0; i <= 80; i += 15) { tb[i / 15] = new newTb(); tb[i / 15].Parent = this; tb[i / 15].Location = new Point(i + i, i + i); // button.Subscribe(tb[i / 15]); } button.Click += new EventHandler(button_Click); } private void button_Click(object sender, EventArgs e) { button.s = "this is clicking"; //button.Notify(); } } public class myButton : Button, IObservable<newTb> { public string s; private List<IObserver<newTb>> observers; public myButton() { observers = new List<IObserver<newTb>>(); } public IDisposable Subscribe(IObserver<newTb> observer) { if (!observers.Contains(observer)) { observers.Add(observer); } return new Unsubscriber(observers, observer); } protected void Notify(newTb tb) { foreach (IObserver<newTb> observer in observers) { observer.OnNext(tb); } } #region Unsubscriber private class Unsubscriber : IDisposable { private List<IObserver<newTb>> observers; private IObserver<newTb> observer; public Unsubscriber(List<IObserver<newTb>> observers, IObserver<newTb> observer) { this.observers = observers; this.observer = observer; } public void Dispose() { if (observer != null && observers.Contains(observer)) { observers.Remove(observer); } } } #endregion class newTb : TextBox, IObserver<string> { string s; public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(string value) { this.Text = value; } } } } 
4
  • +1 Just so that you can have some points to open another bounty :-) Commented Sep 10, 2010 at 17:38
  • If the answer is correct, then you should mark the question as answered so that the bounty can be awarded. Commented Sep 10, 2010 at 17:49
  • but it's not it's another way of imlpment i want to implment as they do in msdn in my own example Commented Sep 10, 2010 at 18:00
  • 1
    You really should work on code readability. Mind that there are some naming conventions in C#, i.e. type name should start with upper case letter. I am afraid that if you would use FxCop or StyleCop to check this code out, it will give you enormous number of errors. Commented Sep 11, 2010 at 17:08

2 Answers 2

5

According to http://msdn.microsoft.com/en-us/library/dd783449.aspx

The IObserver and IObservable interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. The IObservable interface represents the class that sends notifications (the provider); the IObserver interface represents the class that receives them (the observer).

T represents the class that provides the notification information.

In your case the information you pass is a message (a string). In your sample you were passing the control newTB

With the following declaration

 public class ObservableButton : Button, IObservable<string> {} public class ObserverTextBox : TextBox, IObserver<string> {} 

Every thing fall into places.

The method Notify of the classObservableButton can be written this way.

 public void Notify(string text) { foreach (IObserver<string> observer in _Observers) { observer.OnNext(text); } } 

Here the full source code

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ObservableDemo { public class ObservableButton : Button, IObservable<string> { private List<IObserver<string>> _Observers; public ObservableButton() { _Observers = new List<IObserver<string>>(); } IDisposable IObservable<string>.Subscribe(IObserver<string> observer) { if (!_Observers.Contains(observer)) { _Observers.Add(observer); } return new Unsubscriber(_Observers, observer); } public void Notify(string text) { foreach (IObserver<string> observer in _Observers) { observer.OnNext(text); } } private class Unsubscriber : IDisposable { private List<IObserver<string>> observers; private IObserver<string> observer; public Unsubscriber(List<IObserver<string>> observers, IObserver<string> observer) { this.observers = observers; this.observer = observer; } public void Dispose() { if (observer != null && observers.Contains(observer)) { observers.Remove(observer); } } } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ObservableDemo { public class ObserverTextBox : TextBox, IObserver<string> { private IDisposable unsubscriber; void IObserver<string>.OnCompleted() { } void IObserver<string>.OnError(Exception error) { } void IObserver<string>.OnNext(string value) { this.Text = value; this.Refresh(); } public virtual void Subscribe(IObservable<string> provider) { if (provider != null) unsubscriber = provider.Subscribe(this); } public virtual void Unsubscribe() { unsubscriber.Dispose(); } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ObservableDemo { public partial class Form1 : Form { ObservableButton button; public Form1() { InitializeComponent(); button = new ObservableButton(); button.Parent = this; button.Location = new Point(120, 0); button.Text = "click on me!!!"; button.Click += new EventHandler(button_Click); for (int i = 0; i < 8; i++) { ObserverTextBox tb = new ObserverTextBox(); tb.Parent = this; tb.Location = new Point(0 , 30+(i*30)); tb.Width = 300; tb.Subscribe(button); } } private void button_Click(object sender, EventArgs e) { button.Notify(String.Format("{0} this is the message", DateTime.Now)); } void Form1_Load(object sender, System.EventArgs e) { } } } 
Sign up to request clarification or add additional context in comments.

3 Comments

thank u it works can you in-light with some facts I don't understand where i got wrong
Actually I also have a problem with the IObserver/IObservable pattern. I will try to write your problem from scratch tonight.
I changed may answer with this time something that make sense
1

I believe this could be your problem:

class newTb : TextBox, IObserver<string> 

Because what you what you wanted to observe based on this sample:

observers = new List<IObserver<newTb>>(); 

is actually IObserver<newTb>, which is different type than IObserver<string>. Your newTb class does not implement first interface, it only implements the latter. Not sure why this compiles (if it does), though.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.