我想要一个按钮,当按下它时,文本框中会显示一个新字符串
我做错了什么
有人可以告诉我为什么这段代码不起作用? ......
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 :(得分:5)
根据http://msdn.microsoft.com/en-us/library/dd783449.aspx
IObserver和IObservable接口为基于推送的通知提供了一种通用机制, 也称为观察者设计模式。 IObservable接口表示发送通知的类(提供者); IObserver接口表示接收它们的类(观察者)。
T代表提供通知信息的类。
在您的情况下,您传递的信息是一条消息(字符串)。 在您的示例中,您传递了控件newTB
使用以下声明
public class ObservableButton : Button, IObservable<string> {}
public class ObserverTextBox : TextBox, IObserver<string> {}
每件事都落到了地方。
可以用这种方式编写classObservableButton的Notify方法。
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 :(得分:1)
我相信这可能是你的问题:
class newTb : TextBox, IObserver<string>
因为基于这个样本你想要观察的是什么:
observers = new List<IObserver<newTb>>();
实际上是IObserver&lt; newTb&gt;,它与IObserver&lt; string&gt;的类型不同。你的newTb类没有实现第一个接口,它只实现了后者。不知道为什么这会编译(如果确实如此)。