实现了观察者模式的用户控件。
在学习 IssueVision 过程中,提到过观察者模式的用户控件(ChartPanel?),我按自己的设计思路也做了个不伦不类的观察者模式+用户控件,记录下来。
首先,建立一个观察者模式的接口 IObserver.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace IssueVision
{
public interface IObserver //接口声明
{
void NotifyDataChange(ChartData nChartData); //事件,当数据改变时
}
//ChartData 类,表示三类事务,open,work,close
public class ChartData
{
private int n_open;
private int n_work;
private int n_close;
private int n_max;
public int open
{
get
{
return n_open;
}
set
{
n_open = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int work
{
get
{
return n_work;
}
set
{
n_work = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int close
{
get
{
return n_close;
}
set
{
n_close = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int max
{
get
{
return n_max;
}
set
{
n_max = value > 0 ? value : 0;
}
}
}
}
using System.Collections.Generic;
using System.Text;
namespace IssueVision
{
public interface IObserver //接口声明
{
void NotifyDataChange(ChartData nChartData); //事件,当数据改变时
}
//ChartData 类,表示三类事务,open,work,close
public class ChartData
{
private int n_open;
private int n_work;
private int n_close;
private int n_max;
public int open
{
get
{
return n_open;
}
set
{
n_open = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int work
{
get
{
return n_work;
}
set
{
n_work = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int close
{
get
{
return n_close;
}
set
{
n_close = value > 0 ? value : 0;
n_max = value > n_max ? value : n_max;
}
}
public int max
{
get
{
return n_max;
}
set
{
n_max = value > 0 ? value : 0;
}
}
}
}
接着声明主体 ISubject.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace IssueVision
{
public interface ISubject //声明主体接口
{
// 需实现这两个,实现注册和反注册
void Register(IObserver anObject);
void UnRegister(IObserver anObject);
}
}
using System.Collections.Generic;
using System.Text;
namespace IssueVision
{
public interface ISubject //声明主体接口
{
// 需实现这两个,实现注册和反注册
void Register(IObserver anObject);
void UnRegister(IObserver anObject);
}
}
现在新建一个用户控件,放上一个 lbltitle 表示标题,三个 label 分别表示 open , work , close,再放三个 progressbar 表示数量,因为懒得画条形图,所以直接用 progressbar , 不过,用 progressbar 很难看倒是真的:(。,用户控件叫 ChartPanel.cs,代码如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace IssueVision.UserControls
{
public partial class ChartPanel : UserControl , IObserver //指定 IObserver ,表示实现它
{
private string m_title;
private int n_max;
private int n_open;
private int n_working;
private int n_closed;
[Description("图表标题")]
public string Title
{
get
{
return m_title;
}
set
{
m_title = value;
Invalidate();
}
}
[Description("最大数量")]
public int NMAX
{
get
{
return n_max;
}
set
{
n_max = value > 0 ? value : 0;
Invalidate();
}
}
[Description("打开任务数量")]
public int NOpen
{
get
{
return n_open;
}
set
{
n_open = value > 0 ? value : 0;
Invalidate();
}
}
[Description("进行的任务数量")]
public int NWorking
{
get
{
return n_working;
}
set
{
n_working = value > 0 ? value : 0;
Invalidate();
}
}
[Description("关闭的任务数量")]
public int NClosed
{
get
{
return n_closed;
}
set
{
n_closed = value > 0 ? value : 0;
Invalidate();
}
}
public void NotifyDataChange(ChartData nChartData) //实现观察者的 NotifyDataChage,表示当接受到数据变更时应用的动作。
{
//
n_max = nChartData.max;
n_open = nChartData.open;
n_working = nChartData.work;
n_closed = nChartData.close;
Invalidate();
}
public ChartPanel()
{
InitializeComponent();
}
private void ChartPanel_Paint(object sender, PaintEventArgs e)
{
this.lbTitle.Text = m_title;
pbOpen.Minimum = 0;
pbWorking.Minimum = 0;
pbClosed.Minimum = 0;
pbOpen.Maximum = n_max;
pbWorking.Maximum = n_max;
pbClosed.Maximum = n_max;
pbOpen.Value = n_open > n_max ? n_max : n_open;
pbWorking.Value = n_working > n_max ? n_max : n_working;
pbClosed.Value = n_closed > n_max ? n_max : n_closed;
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace IssueVision.UserControls
{
public partial class ChartPanel : UserControl , IObserver //指定 IObserver ,表示实现它
{
private string m_title;
private int n_max;
private int n_open;
private int n_working;
private int n_closed;
[Description("图表标题")]
public string Title
{
get
{
return m_title;
}
set
{
m_title = value;
Invalidate();
}
}
[Description("最大数量")]
public int NMAX
{
get
{
return n_max;
}
set
{
n_max = value > 0 ? value : 0;
Invalidate();
}
}
[Description("打开任务数量")]
public int NOpen
{
get
{
return n_open;
}
set
{
n_open = value > 0 ? value : 0;
Invalidate();
}
}
[Description("进行的任务数量")]
public int NWorking
{
get
{
return n_working;
}
set
{
n_working = value > 0 ? value : 0;
Invalidate();
}
}
[Description("关闭的任务数量")]
public int NClosed
{
get
{
return n_closed;
}
set
{
n_closed = value > 0 ? value : 0;
Invalidate();
}
}
public void NotifyDataChange(ChartData nChartData) //实现观察者的 NotifyDataChage,表示当接受到数据变更时应用的动作。
{
//
n_max = nChartData.max;
n_open = nChartData.open;
n_working = nChartData.work;
n_closed = nChartData.close;
Invalidate();
}
public ChartPanel()
{
InitializeComponent();
}
private void ChartPanel_Paint(object sender, PaintEventArgs e)
{
this.lbTitle.Text = m_title;
pbOpen.Minimum = 0;
pbWorking.Minimum = 0;
pbClosed.Minimum = 0;
pbOpen.Maximum = n_max;
pbWorking.Maximum = n_max;
pbClosed.Maximum = n_max;
pbOpen.Value = n_open > n_max ? n_max : n_open;
pbWorking.Value = n_working > n_max ? n_max : n_working;
pbClosed.Value = n_closed > n_max ? n_max : n_closed;
}
}
}
下面是设计器形成的,ChartPanel的设计代码,一并留下
namespace IssueVision.UserControls
{
partial class ChartPanel
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
组件设计器生成的代码
private System.Windows.Forms.Panel pnlTop;
private System.Windows.Forms.Label lbTitle;
private System.Windows.Forms.Label lblOpen;
private System.Windows.Forms.Label lblWorking;
private System.Windows.Forms.Label lblclosed;
private System.Windows.Forms.ProgressBar pbOpen;
private System.Windows.Forms.ProgressBar pbWorking;
private System.Windows.Forms.ProgressBar pbClosed;
}
}
{
partial class ChartPanel
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
组件设计器生成的代码
private System.Windows.Forms.Panel pnlTop;
private System.Windows.Forms.Label lbTitle;
private System.Windows.Forms.Label lblOpen;
private System.Windows.Forms.Label lblWorking;
private System.Windows.Forms.Label lblclosed;
private System.Windows.Forms.ProgressBar pbOpen;
private System.Windows.Forms.ProgressBar pbWorking;
private System.Windows.Forms.ProgressBar pbClosed;
}
}
新建一个窗体,放上刚才的用户控件 chartpanel1,放置 textbox2,3,4 ,放一个按钮。
public class SubjectImpl:ISubject //被观察者的实现
{
protected Hashtable _observerContaind = new Hashtable();
public void Register(IObserver anObserver)
{
_observerContaind.Add(anObserver,anObserver);
}
public void UnRegister(IObserver anObserver)
{
_observerContaind.Remove(anObserver);
}
public void NotifyObservers(ChartData n_data)
{
foreach (IObserver anObserver in _observerContaind.Keys)
{
anObserver.NotifyDataChange(n_data);
}
}
}
public class MyData :SubjectImpl
{
private ChartData _cd = new ChartData();
public ChartData CD
{
get
{
return _cd;
}
set
{
_cd = value;
base.NotifyObservers(_cd);
}
}
}
{
protected Hashtable _observerContaind = new Hashtable();
public void Register(IObserver anObserver)
{
_observerContaind.Add(anObserver,anObserver);
}
public void UnRegister(IObserver anObserver)
{
_observerContaind.Remove(anObserver);
}
public void NotifyObservers(ChartData n_data)
{
foreach (IObserver anObserver in _observerContaind.Keys)
{
anObserver.NotifyDataChange(n_data);
}
}
}
public class MyData :SubjectImpl
{
private ChartData _cd = new ChartData();
public ChartData CD
{
get
{
return _cd;
}
set
{
_cd = value;
base.NotifyObservers(_cd);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
ChartData mycd=new ChartData();
mycd.open=Convert.ToInt16(textBox2.Text);
mycd.work=Convert.ToInt16(textBox3.Text);
mycd.close=Convert.ToInt16(textBox4.Text);
MyData md = new MyData();
md.Register(chartPanel1);
md.CD = mycd;
}
{
ChartData mycd=new ChartData();
mycd.open=Convert.ToInt16(textBox2.Text);
mycd.work=Convert.ToInt16(textBox3.Text);
mycd.close=Convert.ToInt16(textBox4.Text);
MyData md = new MyData();
md.Register(chartPanel1);
md.CD = mycd;
}
呼,终于完了,点此 button 后,chartpanel 将会更改,不过,这么做会不会太麻烦了?