如标题,如果想实现类似delphi的dbgrid+controls(textbox等)+navagator的数据库表的维护界面大家都是怎样实现的,我想有以下几种方式,大家有什么好的方法,请给予指点。1。
   在datagrid上直接编辑修改,先保存到关联的dataset,再通过提交按钮提交到数据库(用sqlDataAdaptor)。缺点:是在datagrid上录入很不方便,有些关联表的数据不是很好处理,还有错误控制不是很好控制。而且维护完后,还要提交,不符合录入人员工作习惯,如果忘记容易造成白做了。2。
  datagrid只读,在wincontrols上编辑数据,然后直接提交到数据库(其实也分为两种情况一种是先保存到dataset,点提交按钮再提交到数据库,一种是直接提交到数据库,前者在第1点中阐述了,不符合操作习惯就不作考虑了)。
  编辑控件这时又可分两种选择,一种是做数据绑定(databindings),一种不作数据绑定(不知哪一种更合理);
  而在提交到数据库时又分为两种情况,一种是用类似sqlDataAdaptor.update()的方式(其中insert,delete等command的语句由ide构造时生成或者由sqlCommandbuilder动态生成,但后者限制较多),一种是自己定制sqlcommand进行提交到数据库。前者在设计期就需要提供sqldataAdaptor和dataset等信息,每个界面都要事先设置好,感觉不是很灵活,但好处是提交数据库后,可以直接合并到原有的dataset,而后者只能人为的做重新添充dataset来保持数据一致,这样做和以前从从c/s两层结构没有什么大的区别了,甚至效率更低,需要反复地与数据库服务器通讯,这似乎有违dataset离线数据库的初衷啊。而且提交两种方式有共同的问题就是,当更新一条记录后,怎样保证提交数据库后返回的dataset中相应的datatable位置停留在当前记录(也就是说,怎样保证更新完一条记录后,datagrid的当前行还是这条记录)。
3。
  如果使用多层结构,比如使用数据访问层,中间层使用的ORM,在表示层(UI层),怎样配合使用datagrid。orm中对实体进行crud后,变化怎样体现在datagrid中,需要重新填充(刷新)吗?
4。
 另外,当datagrid的行改变时,如果不使用wincontrol的databindings,用谁的什么事件可以取得当前记录的当前值并把它填充到wincontrol(例如textbox)中去。我非常想知道大家在.net winform项目,是怎样实现数据维护的,是像以往vb6,delphi中一样双击dbgrid弹出编辑界面,删除直接在dbgrid使用快捷键,还是有其他方式?如果是前者,那末dbgird以及它的数据源在update后又是怎样做的刷新?因为delphi使用的是ado在线连接数据库,而.net使用的是ado.net离线连接啊,如果等同处理,岂不是浪费新技术啊。请各位指教。

解决方案 »

  1.   

    是分不够多哈哈这个完全靠项目的需求
    个人认为2号方案结合3号方案比较通用,界面较为友好
    使用databindings也比较方便
      

  2.   

    Firestone2003(笨笨小猪):
    分不够,我可以加的,请您不吝赐教,因为在写方案啊
      

  3.   

    是像以往vb6,delphi中一样双击dbgrid弹出编辑界面,删除直接在dbgrid使用快捷键我一般都是这么做的!3号问题,建议参看duwamish的结构因为DataSet是离线浏览,所以一次做完所有的更新后在Updatedatabindings是为了将数据源与控件结合的,我不明白你为什么不用,好用又节省自己编写的代码量。
    使用其他的方法你查看一下DataGridView下面的相关时间,是有详细描述的
      

  4.   

    我觉得不能说哪用哪一种方法好,应该根据具体情况采用不同的方式,比如是单表或没行字段类型比较单一就中采用第1种方法,程序可以让用户不用再点一次提交的。对于表字段比较多,校验格式比较多的可采用wincontrol来录入,但不用databinding应该更好,用datagrid来显示查找录入结果。如果你是用VS2005的话,尽量采用2005的新的数据操作方面的功能,datasource,bindingsource,bindingnavigator,bindlinglist<T>,datagridview.
      

  5.   

    Firestone2003(笨笨小猪) :
    因为DataSet是离线浏览,所以一次做完所有的更新后在Update
    这个我知道的,我是问这样的方式好不好,为什么?
    lincon77() :对于表字段比较多,校验格式比较多的可采用wincontrol来录入,但不用databinding应该更好,用datagrid来显示查找录入结果。为什么?怎样做提交后的刷新定位?请详细阐述比如是单表或没行字段类型比较单一就中采用第1种方法,程序可以让用户不用再点一次提交的。是怎样实现的?是rowchange事件做提交吗?这样的话和ado的在线连接好像差不多喔?但还是有datagrid的刷新定位问题,比如有个自动增加字段,在提交数据库后和dateset中的值可能不同,怎样把它映射回dataset,并在datagrid体现出来哪?请指教也请笨笨小猪能详细阐述一下。
      

  6.   

    至于你所说的,我觉都是可以,主要是细节如何操作的问题。方法一:在同一个窗体中,DataAdapter+DataSet+DataGrid,这就相当于excel表格,当直接在datagrid中录入后,会反映到所绑定的数据源中,而至于你所说的如下这两个问题,很好解决:to 1.有些关联表的数据不是很好处理,还有错误控制不是很好控制。
    查询和更新都是command,如果是多个表的话,更新操作你可以在服务器端建立存储(这也是最好的方法,保证了操作的一致性),那么分别设定给DataAdapter即可。to 2.而且维护完后,还要提交,不符合录入人员工作习惯,如果忘记容易造成白做了。
    这点,你可以在关闭窗体的时候,通过绑定的数据源的GetChanges方法判断是否有数据没有更新,然后作出相应的提示。方法二,弹出窗体进行修改,显示窗体我就不多说了,就是DataSet+DataGrid,然后设置DataGrid为ReadOnly即可。至于双击弹出窗体,你可以通过mousedown获得当前行,然后找到数据源的记录,把它作为参数传递给弹出窗体,那么对于当前DataRow的操作,可以在弹出窗体上进行处理,之后更新数据库,可以用command直接操作。返回到主窗体后,调用DataGrid所绑定数据源的AcceptChanges即可把更新后的数据反显到datagrid中。
      

  7.   

    to 因为delphi使用的是ado在线连接数据库,而.net使用的是ado.net离线连接啊,如果等同处理至于在C#中也是可以的,你不必要重复的open和close数据库连接,只需要销毁真正操作对象,例如command,dataadapter即可,可以达到和delphi一样的效果。
      

  8.   

    Knight94(愚翁) :非常感谢回复方式一的解决方法我是知道的,只是个人感觉这种方法不是很合理。你是怎么觉得的,为什么?方式二 ”返回到主窗体后,调用DataGrid所绑定数据源的AcceptChanges即可把更新后的数据反显到datagrid中.“
      1,因为你后台(在弹出窗体中)是直接用sqlcommand做的,而原窗体的DataGrid绑定的数据源并没有发生改变,acceptchanges什么也没有发生啊。还比如有个自动增加字段,在提交数据库后和dateset中的值可能不同,怎样把它映射回dataset,并在datagrid体现出来哪?也就是刷新和定位问题。请指教
      2。mousedown事件我觉得值得商榷,是否应该用bindcontext好一些?就算要用,也得用mouseup啊。
      

  9.   

    to 方式二 ”返回到主窗体后,调用DataGrid所绑定数据源的AcceptChanges即可把更新后的数据反显到datagrid中.“
    1,因为你后台(在弹出窗体中)是直接用sqlcommand做的,而原窗体的DataGrid绑定的数据源并没有发生改变,acceptchanges 什么也没有发生啊。还比如有个自动增加字段,在提交数据库后和dateset中的值可能不同,怎样把它映射回dataset,并在datagrid体现出来哪?也就是刷新和定位问题。请指教传递过去DataRow即可,在弹出窗体直接修改DataRow,然后用DataRow结合Command更新数据库。
    至于新建,也可先从DataTable新建一个DataRow,然后传递过去,至于自增字段,在操作之后通过查询获得后反过来修改DataRow。to 2。mousedown事件我觉得值得商榷,是否应该用bindcontext好一些?就算要用,也得用mouseup啊。为什么要用mouseup呢,
    用mousedown的事件,通过鼠标位置用hittext找到当前行,然后再找到bindcontext。
      

  10.   

    datagrid的刷新定位问题,比如有个自动增加字段,在提交数据库后和dateset中的值可能不同,怎样把它映射回dataset?ADO.Net用DataSet实现离线的工作方式,只有更新后才能正确返回自动增量字段的值。如果单用户操作的话比较简单,实际上是同时有多个用户要访问操作相同的后台数据库数据,你在前台修改新加了数据,提交时要考虑并发问题的,建议在这种情况下采用ADO的工作模式比较好。
      

  11.   

    愚翁:
    to 2。mousedown事件我觉得值得商榷,是否应该用bindcontext好一些?就算要用,也得用mouseup啊。为什么要用mouseup呢,
    用mousedown的事件,通过鼠标位置用hittext找到当前行,然后再找到bindcontext。------------------------------------------
    我说的不对,mouseup不行,当初像是因为要从bindcontext里取数据,而执行次序是mousedown,改变记录指针,mouseup,所以这莫考虑。但mouseup事也比较多,例如点击一行,在另一行mouseup。因为mousedown的时候,我要点击数据区域以外的区域,比如标题栏,它也会响应的(还要加额外的判断,不方便),而用hittext找到当前行号的话,如果使用row[]还行(但可能字段不全部显示),但如果像您说的“然后再找到bindcontext”(怎么去找?),那还不如直接用bindcontext[,].current哪,何必用mousedown啊。
      

  12.   

    根据我的经验,用户都希望要求或习惯象Excel的操作方式的,我想离线的工作方式就是MS的用户体验的结果吧。但离线的工作方式并要求用到所有的块合,实际上在有些场合用离线的工作方式效率更低的,大家不觉得吗?
      

  13.   

    How to handle double-click event in datagrid?reference:
    http://www.syncfusion.com/faq/windowsforms/Search/869.aspx
      

  14.   

    Knight94(愚翁) :
    感谢提供mouse处理的方法,但其实我主要想问和解决的是与数据操作有关的问题啊---用hittext找到当前行号的话,如果使用row[]还行(但可能字段不全部显示),但如果像您说的“然后再找到bindcontext”(怎么去找?),那还不如直接用bindcontext[,].current哪,何必用mousedown事件啊。我主要想知道您是怎样实现你说的“然后再找到bindcontext”,请指教。
      

  15.   

    to 但如果像您说的“然后再找到bindcontext”(怎么去找?),那还不如直接用bindcontext[,].current哪,何必用mousedown事件啊。我主要想知道您是怎样实现你说的“然后再找到bindcontext”,请指教你的方法是可以的,可以直接通过bindcontext去获得。其实我所说的意思是,在mousedown中触发bindcontext.current发生变化,然后再去获得。
      

  16.   

    Knight94(愚翁):还得叨扰
    其实我所说的意思是,在mousedown中触发bindcontext.current发生变化,然后再去获得。还请详细解释你是怎样在mousedown中触发的bindcontext.current发生变化,我觉得在mousedown
    事件完成后(比如点击下一条记录),系统自动完成bindcontext.current变化。我关键是想知道是在什么事件里触发同一窗体里wincontrol(用来显示字段内容例如textbox,在不用databindings的情况下下)的刷新,如果用mousedown,即使在同一记录(不改变行)的情况下单击,事件也要执行的,重复!在delphi里有dataset的记录位置改变事件(例如adoquery的AfterScroll),在它里做就行了。在.net中对应的用什么组件的什么事件好哪?
      

  17.   

    to 还请详细解释你是怎样在mousedown中触发的bindcontext.current发生变化,我觉得在mousedown
    事件完成后(比如点击下一条记录),系统自动完成bindcontext.current变化。不一定,看鼠标的位置而定,即hittext不一定是row。
      

  18.   

    to 我关键是想知道是在什么事件里触发同一窗体里wincontrol(用来显示字段内容例如textbox,在不用databindings的情况下下)的刷新,如果用mousedown,即使在同一记录(不改变行)的情况下单击,事件也要执行的,重复!如果你做的是double-click弹出窗体的话,这样做是对的,因为有可能连续对同一条记录进行修改。
      

  19.   

    此外,你可以通过绑定源的事件来处理,参看“BindingManagerBase”
    ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/cpref/html/frlrfsystemwindowsformsbindingmanagerbaseclasscurrentchangedtopic.htm
    ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/cpref/html/frlrfsystemwindowsformsbindingmanagerbaseclasspositionchangedtopic.htm如果说要模拟delphi来说,currentchanged事件是最好的替换。
      

  20.   

    Knight94(愚翁):
    to:
    to 我关键是想知道是在什么事件里触发同一窗体里wincontrol(用来显示字段内容例如textbox,在不用databindings的情况下下)的刷新,如果用mousedown,即使在同一记录(不改变行)的情况下单击,事件也要执行的,重复!如果你做的是double-click弹出窗体的话,这样做是对的,因为有可能连续对同一条记录进行修改。如果你做的是double-click弹出窗体的话,这样做是对的?是什么意思啊,我的意思是说在同一个窗体里编辑的话,用mousedown事件,容易造成重复执行,效率低下。你这句话,怎么理解哪?感谢,能留下msn什么的吗?我的mail:[email protected]
      

  21.   

    Firestone2003(笨笨小猪) ,Knight94(愚翁) 等大侠不要急,我想让大家讨论一下,明后天再给分。