当前位置: 首页 > 编程语言 > C#

C#学习教程:.Net中的同步ListView分享

时间:2023-04-10 19:38:14 C#

C#学习教程:.Net中的同步ListView到目前为止,我已经能够让子ListViews在主滚动条按钮被点击时更新它们的视图。问题是当单击和拖动ScrollBar本身时,子ListViews不会更新。我查看了使用Spy++发送的消息,并且发送了正确的消息。这是我当前的代码:publicpartialclassLinkedListViewControl:ListView{[DllImport("User32.dll")]privatestaticexternboolSendMessage(IntPtrhwnd,UInt32msg,IntPtrwParam,IntPtrlParam);[DllImport("User32.dll")]privatestaticexternboolShowScrollBar(IntPtrhwnd,intwBar,boolbShow);[DllImport("user32.dll")]privatestaticexternintSetScrollPos(IntPtrhWnd,intwBar,intnPos,boolbRedraw);私有常量intWM_HSCROLL=0x114;私人常量intSB_HORZ=0;私人常量intSB_VERT=1;私人常量intSB_CTL=2;私人常量intSB_BOTH=3;私人常量intSB_THUMBPOSITION=4;私人常量intSB_THUMBTRACK=5;私人常量intSB_ENDSCROLL=8;publicLinkedListViewControl(){InitializeComponent();}privatereadonlyList_linkedListViews=newList();publicvoidAddLinkedView(ListViewlistView){if(!_linkedListViews.Contains(listView)){_linkedListViews.Add(listView);隐藏滚动条(列表视图);}}公共布尔删除LinkedView(ListViewlistView){返回_linkedListViews.Remove(listView);}privatevoidHideScrollBar(ListViewlistView){//确保列表视图是可滚动的listView.Scrollable=true;//然后隐藏滚动条ShowScrollBar(listView.Handle,SB_BOTH,false);}protectedoverridevoidWndProc(refMessagemsg){if(_linkedListViews.Count>0){//寻找WM_HSCROLL消息if(msg.Msg==WM_HSCROLL){foreach(ListViewviewin_linkedListViews){SendMessage(view.Handle,WM_HSCROLL,msg.WParam,IntPtr.Zero);}}}}}根据MSTech论坛上的这篇文章,我尝试获取并处理SB_THUMBTRACK事件:protectedoverridevoidWndProc(refMessagemsg){if(_linkedListViews.Count>0){//LookforWM_HSCROLLmessagesif(msg.Msg==WM_HSCROLL){Int16hi=(Int16)((int)msg.WParam>>16);Int16lo=(Int16)msg.WParam;foreach(ListViewviewin_linkedListViews){if(lo==SB_THUMBTRACK){SetScrollPos(view.Handle,SB_HORZ,hi,true);intwParam=4+0x10000*嗨;SendMessage(view.Handle,WM_HSCROLL,(IntPtr)(wParam),IntPtr.Zero);}else{SendMessage(view.Handle,WM_HSCROLL,msg.WParam,IntPtr.Zero);}}}}//将消息传递给默认的handler.base.WndProc(refmsg);这将更新子ListViewScrollBar的位置,但不会更改子中的实际视图所以我的问题是:是否可以在拖动主ListViewScrollBar时更新子ListView?如果是这样,如何?我试图做同样的事情,在搜索之后我在这里找到了你的代码,这有帮助,但当然没有解决问题。但是在玩弄之后,我找到了解决方案。您可以使用它来使滑块工作,正如我意识到的那样,因为滚动按钮可以工作。换句话说,当SB_THUMBTRACK事件进入时,我发出重复的SB_LINELEFT和SB_LINERIGHT事件,直到我的子ListView接近母版的位置。是的,它并不完美,但已经足够接近了。在我的示例中,我的主ListView称为“reportView”,我的子ListView称为“summaryView”。这是我的相关代码:publicclassMyListView:ListView{publiceventScrollEventHandlerHScrollEvent;protectedoverridevoidWndProc(refSystem.Windows.Forms.Messagemsg){if(msg.Msg==WM_HSCROLL&&HScrollEvent!=null)HScrollEvent(this,newScrollEventArgs(ScrollEventType.ThumbTrack,(int)msg.WParam));base.WndProc(参考消息);然后是事件处理程序本身:reportView.HScrollEvent+=newScrollEventHandler((sender,e)=>{if((ushort)e.NewValue!=SB_THUMBTRACK)SendMessage(summaryView.Handle,WM_HSCROLL,(IntPtr)e.NewValue,IntPtr.Zero);else{intnewPos=e.NewValue>>16;intoldPos=GetScrollPos(reportView.Handle,SB_HORZ);intpos=GetScrollPos(summaryView.Handle,SB_HORZ);intlst;if(pos!=newPos)if(posnewPos&&oldPos>newPos)do{lst=pos;SendMessage(summaryView.Handle,WM_HSCROLL,(IntPtr)SB_LINELEFT,IntPtr.Zero);}while((pos=GetScrollPos(summaryView.Handle,SB_HORZ))>newPos&&pos!=lst);}});抱歉while循环的奇怪格式,但这就是我喜欢写的顺便说一下,下一个问题是摆脱子ListView中的滚动条。我注意到您有一个名为HideScrollBar的方法。这对我不起作用。就我而言,我发现一个更好的解决方案是将滚动条留在那里,但“覆盖”它。我还对列标题执行此操作。我只是将我的子控件滑动到主控件下以覆盖列标题。然后我拉伸孩子从包含它的面板中掉出来。然后为了沿着包含面板的边缘提供一些边框,我抛出一个控件来覆盖我的子ListView的可见底部边缘。结果看起来还不错。我还添加了一个事件处理程序来同步更改列宽,如下所示:reportView.ColumnWidthChanging+=newColumnWidthChangingEventHandler((sender,e)=>{summaryView.Columns[e.ColumnIndex].Width=e.NewWidth;});虽然这一切看起来都是废话,但它对我有用。这只是让精神流动的猜测,所以做你想做的:在主列表的滚动处理程序中,你调用子列表的滚动处理程序(从主列表传递sender和eventargs)?将此添加到您的表单加载中:masterList.Scroll+=newScrollEventHandler(this.masterList_scroll);其中引用了这个:privatevoidmasterList_scroll(Objectsender,System.ScrollEventArgse){childList_scroll(sender,e);}privatevoidchildList_scroll(Objectsender,System.ScrollEventArgse){childList.value=e.NewValue}我将创建自己的类,它继承自ListView以显示垂直和水平滚动事件。然后我会在我的表单中创建滚动处理程序来同步这两个控件这是示例代码,应该允许列表视图发布滚动事件:publicclassMyListView:System.Windows.Forms.ListView{constintWM_HSCROLL=0x0114;constintWM_VSCROLL=0x0115;私有ScrollEventHandlerevtHScroll_m;私有ScrollEventHandlerevtVScroll_m;公共事件ScrollEventHandlerOnHScroll{添加{evtHScroll_m+=值;}移除{evtHScroll_m-=值;}}公共事件ScrollEventHandlerOnHVcroll{添加{evtVScroll_m+=值;}移除{evtVScroll_m-=值;}}protectedoverridevoidWndProc(refSystem.Windows.Forms.Messagemsg){if(msg.Msg==WM_HSCROLL&&evtHScroll_m!=null){evtHScroll_m(this,newScrollEventArgs(ScrollEventType.ThumbTrack,msg.WParam.ToInt32()));}if(msg.Msg==WM_VSCROLL&&evtVScroll_m!=null){evtVScroll_m(this,newScrollEventArgs(ScrollEventType.ThumbTrack,msg.WParam.ToInt32()));}base.WndProc(参考消息);现在处理表单中的滚动事件:设置PInvoke方法以便能够将Windows消息发送到控件:[DllImport("user32.dll",CharSet=CharSet.Auto,SetLastError=true)]publicstaticexternintSendMessage(IntPtrhWnd,[MarshalAs(UnmanagedType.U4)]intiMsg,intiWParam,intiLParam);设置事件处理器(lstMaster和lstChild是两个listbox):lstMaster.OnVScroll+=newScrollEventHandler(this.lstMaster_OnVScroll);lstMaster.OnHScroll+=newScrollEventHandler(this.lstMaster_OnHScroll);constintWM_HSCROLL=0x0114;constintWM_VSCROLL=0x0115;privatevoidlstMaster_OnVScroll(Objectsender,System.ScrollEventArgse){SendMessage(lstChild.Handle,WM_VSCROLL,(IntPtr)e.NewValue,IntPtr.Zero);}privatevoidlstMaster_OnHScroll(Objectsender,System.ScrollEventArgse){SendMessage(lstChild.Handle,WM_HSCROLL,(IntPtr)e.NewValue,IntPtr.Zero);}一个天真的解决方案是处理父列表视图中的绘制消息,并检查链接列表视图是否显示正确的数据,如果不正确,通过调用EnsureVisible方法数据更新它们以显示正确的。以上就是C#学习教程:.Net中的同步ListView分享的全部内容,如果对你有用,还需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处: