一般我们在做数据内容展示的时候,只需把该对象的详细信息,分门别类放到一个窗体展示即可,在我的Winform开发框架中,一般也侧重于使用这种传统的方式,只是通过窗体继承方式,把通用的窗体操作封装到基类实现而已。如一般的数据展示窗体,包括查看数据,编辑数据、新建数据等内容的窗体,如下所示。
对于以上窗体,如果仅仅是看当前记录的数据,是没什么问题的,但如果要看下一个记录的、上一个记录的数据,就要关闭该窗体,然后重新打开,操作起来会稍微麻烦一些。如果我们在这个窗体上设计一个导航栏,那么界面会显得友好一些,界面效果如下所示。
这样就可以随意在各个记录之间浏览数据了,原来的保存或或其它操作,并没有影响,两全其美,何乐不为呢?
其实这样的操作,已经是比较通用的界面元素部分,因此可以把它封装到基类中即可,我们在之类只需要传入必要的数据给他即可,首先我们设计一个导航控件,如下所示。
然后再编辑窗体基类中嵌入对应的控件即可,由于需要在窗体子类中调整导航控件的位置,因此把它的属性设置为Protected即可,如下图所示。
这个窗体里面集成了DataNavigator用户控件,该控件除了响应如分页的导航按钮事件外,就是响应和显示对应的记录位置而已,因此在其中编写相关的处理代码即可,如下所示。
{
public delegate void PostionChangedEventHandler(object sender, EventArgs e);
public partial class DataNavigator : DevExpress.XtraEditors.XtraUserControl
{
public event PostionChangedEventHandler PositionChanged;
private int m_CurrentIndex = 0;//当前的位置
public List<string> IDList = new List<string>();
/// <summary>
/// 获取或设置索引值
/// </summary>
public int CurrentIndex
{
get { return m_CurrentIndex; }
set
{
m_CurrentIndex = value;
ChangePosition(value);
}
}
public DataNavigator()
{
InitializeComponent();
}
private void btnFirst_Click(object sender, EventArgs e)
{
ChangePosition(0);
}
private void btnPrevious_Click(object sender, EventArgs e)
{
ChangePosition(m_CurrentIndex - 1);
}
private void btnNext_Click(object sender, EventArgs e)
{
ChangePosition(m_CurrentIndex + 1);
}
private void btnLast_Click(object sender, EventArgs e)
{
ChangePosition(IDList.Count - 1);
}
private void EnableControl(bool enable)
{
this.btnFirst.Enabled = enable;
this.btnLast.Enabled = enable;
this.btnNext.Enabled = enable;
this.btnPrevious.Enabled = enable;
}
private void ChangePosition(int newPos)
{
int count = IDList.Count;
if (count == 0)
{
EnableControl(false);
this.txtInfo.Text = "";
}
else
{
EnableControl(true);
newPos = (newPos < 0) ? 0 : newPos;
m_CurrentIndex = ((count - 1) > newPos) ? newPos : (count - 1);
this.btnPrevious.Enabled = (m_CurrentIndex > 0);
this.btnNext.Enabled = m_CurrentIndex < (count - 1);
this.txtInfo.Text = string.Format("{0}/{1}", m_CurrentIndex + 1, count);
if (PositionChanged != null)
{
PositionChanged(this, new EventArgs());
}
}
}
private void DataNavigator_Load(object sender, EventArgs e)
{
}
}
而编辑窗体的基类也需要对控件的事件进行相应的处理,如下所示。我们看到,这个基类需要子类窗体传入一个当前显示的ID(或其它唯一标示)和ID集合,作为数据导航之用,并且对导航控件位置变化的事件进行处理,传入给其新的ID(或其它唯一标示),然后窗体根据这个ID显示相应的数据。
{
public string ID = string.Empty; // 主键主键
public List<string> IDList = new List<string>();//所有待展示的ID列表
public BaseEditForm()
{
InitializeComponent();
this.dataNavigator1.PositionChanged += new ParkDeviceUserMis.UI.BaseUI.PostionChangedEventHandler(dataNavigator1_PositionChanged);
}
private void dataNavigator1_PositionChanged(object sender, EventArgs e)
{
this.ID = IDList[this.dataNavigator1.CurrentIndex];
DisplayData();
}
最后在使用的时候,一般在查询界面中,需要弹出编辑窗体的事件响应操作中,传入当前显示的ID和总的ID字段集合即可,如下实现代码。
{
string ID = this.winGridViewPager1.gridView1.GetFocusedRowCellDisplayText("Id");
List<string> IDList = new List<string>();
for (int i = 0; i < this.winGridViewPager1.gridView1.RowCount; i++ )
{
string strTemp = this.winGridViewPager1.GridView1.GetRowCellDisplayText(i, "Id");
IDList.Add(strTemp);
}
FrmEditPark dlg = new FrmEditPark();
dlg.ID = ID;
dlg.IDList = IDList;
if (DialogResult.OK == dlg.ShowDialog())
{
BindData();
}
}
这样我们就看到开始介绍的窗体效果,如下所示。