Observer implementation
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)
{
}
}
}