2010-09-07 14 views
6

Quiero un botón que cuando se empuja una nueva cadena es showen en los cuadros de textoaplicación # 4 observador

lo que estoy haciendo mal

puede somone INLIGHT mí por qué doesnt este código funciona? ...

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; 
      } 
     } 
    } 
} 
+0

+1 Solo para que pueda tener algunos puntos para abrir otra recompensa :-) – SKG

+0

Si la respuesta es correcta, entonces debe marcar la pregunta como respondida para que se pueda otorgar la recompensa. –

+0

pero no es otra forma de imposición que quiero implementar, como lo hacen en msdn en mi propio ejemplo –

Respuesta

5

Según http://msdn.microsoft.com/en-us/library/dd783449.aspx

Las interfaces IObserver y IObservable proporcionan un mecanismo generalizado para la notificación de instalación automática, también conocido como el patrón de diseño observador. La interfaz IObservable representa la clase que envía notificaciones (el proveedor); la interfaz IObserver representa la clase que los recibe (el observador).

T representa la clase que proporciona la información de notificación.

En su caso, la información que pasa es un mensaje (una cadena). En su muestra que estábamos pasando el control newtb

con la siguiente declaración

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

Cada cosa caen en lugares.

El método Notify of the classObservableButton se puede escribir de esta manera.

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

Aquí la fuente completo código

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) 
     { 
     } 
    } 
} 
+0

gracias, funciona, ¿puedes aclarar algunos hechos? No entiendo de dónde me equivoqué. –

+0

En realidad, también tengo un problema con el patrón IObserver/IObservable. Trataré de escribir su problema desde cero esta noche. –

+0

muchas gracias. –

1

Creo que esto podría ser su problema:

class newTb : TextBox, IObserver<string> 

Debido a que lo que lo que quería observar basado en esta muestra:

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

es en realidad IObser ver <newTb>, que es un tipo diferente de IObserver <cadena>. Su clase newTb no implementa la primera interfaz, solo implementa la última. Sin embargo, no estoy seguro de por qué esto compila (si es que lo hace).

Cuestiones relacionadas