实现了观察者模式的用户控件。

在学习 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;
            }

        }


    }

}


 

接着声明主体 ISubject.cs

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

    }

}


下面是设计器形成的,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;
    }

}

新建一个窗体,放上刚才的用户控件 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);
            }

        }


    }

 

 

        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;

        }


 


 

呼,终于完了,点此 button 后,chartpanel 将会更改,不过,这么做会不会太麻烦了?

posted on 2007-08-14 17:06  qufo  阅读(267)  评论(0编辑  收藏  举报

导航