c # 4 реализация наблюдателя - PullRequest
6 голосов
/ 07 сентября 2010

Мне нужна кнопка, чтобы при нажатии на нее в текстовых полях появлялась новая строка

что я делаю не так

может что-то подсказать, почему этот код не работает?...

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

Ответы [ 2 ]

5 голосов
/ 07 сентября 2010

В соответствии с http://msdn.microsoft.com/en-us/library/dd783449.aspx

Интерфейсы IObserver и IObservable предоставляют обобщенный механизм для push-уведомлений, также известный как шаблон проектирования наблюдателя.Интерфейс IObservable представляет класс, который отправляет уведомления (поставщик);интерфейс IObserver представляет класс, который их получает (наблюдатель).

T представляет класс, который предоставляет информацию уведомления.

В вашем случае передаваемая вами информация является сообщением (строкой).В вашем примере вы передавали элемент управления newTB

Со следующим объявлением

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

Каждая вещь попадает на свои места.

Метод Notify ofclassObservableButton может быть написан таким образом.

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

Здесь полный исходный код

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)
        {
        }
    }
}
1 голос
/ 11 сентября 2010

Я полагаю, что это может быть вашей проблемой:

class newTb : TextBox, IObserver<string>

Потому что то, что вы хотели наблюдать на основе этого примера:

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

на самом деле IObserver ,отличается от IObserver .Ваш класс newTb не реализует первый интерфейс, он только реализует последний.Не уверен, почему это компилируется (если это так).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...