一般我们在做数据内容展示的时候,只需把该对象的详细信息,分门别类放到一个窗体展示即可,在我的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();
}
}
这样我们就看到开始介绍的窗体效果,如下所示。