使用WPF制作视频监控多画面切换
程序员文章站
2022-04-15 16:57:34
前言 曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用WPF开发的,所以当时就做了一个多画面切换组件,效果如下: 功能设计前提: 由于要使用海康大华天地伟业等视频厂家的视频,对接的方式是通过各个厂家提供的SDK(官网下载),由于播放视频的时候需要传递控 ......
前言
曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用wpf开发的,所以当时就做了一个多画面切换组件,效果如下:
功能设计前提:
由于要使用海康大华天地伟业等视频厂家的视频,对接的方式是通过各个厂家提供的sdk(官网下载),由于播放视频的时候需要传递控件的句柄(handle),所以要在wpf中使用system.windows.forms下的控件panel
具体实现:
1、 实现多画面类multiview,主要提供页面初始化、设置当前画面等功能
public static class multiview { public static int currentmodel = 0; public static dictionary<int, cellpanel> dictpanel = null; private static grid originalgrid = null; private static grid tempgrid1 = new grid(); private static grid tempgrid2 = new grid(); private static int maxcellnums = 0; /// <summary> /// 初始化页面 /// </summary> /// <param name="grid">主体</param> /// <param name="cellnums">最大画面数</param> public static void initgrid(grid grid, int cellnums) { multiview.originalgrid = grid; multiview.maxcellnums = cellnums; multiview.dictpanel = new dictionary<int, cellpanel>(); for (int index = 1; index <= multiview.maxcellnums; index++) { cellpanel cellpanel = new cellpanel(); cellpanel.index = index; multiview.dictpanel.add(index, cellpanel); } } /// <summary> /// 设置当前画面数 /// </summary> /// <param name="model"></param> public static void setcurrentmodel(int model) { switch (model) { case 1: multiview.setmodelbycolumnandrow(1, 1); break; case 3: multiview.setmodel3(); break; case 4: multiview.setmodelbycolumnandrow(2, 2); break; case 6: multiview.setmodel6(); break; case 8: multiview.setmodel8(); break; case 9: multiview.setmodelbycolumnandrow(3, 3); break; case 10: multiview.setmodel10(); break; case 16: multiview.setmodelbycolumnandrow(4, 4); break; case 25: multiview.setmodelbycolumnandrow(5, 5); break; } multiview.currentmodel = model; } /// <summary> /// 获取当前画面 /// </summary> /// <returns></returns> public static cellpanel currentcellpanel() { for (int index = 1; index <= multiview.maxcellnums; index++) { if (multiview.dictpanel[index].selected) { return multiview.dictpanel[index]; } } return null; } /// <summary> /// 通过行列数设置画面分割 /// </summary> /// <param name="column">列</param> /// <param name="row">行</param> public static void setmodelbycolumnandrow(int column, int row) { multiview.clear(); multiview.createcolumnandrow(multiview.originalgrid, row, column); int num = 1; for (int rowindex = 0; rowindex < row; rowindex++) { for (int columnindex = 0; columnindex < column; columnindex++) { cellpanel cellpanel = multiview.dictpanel[num]; grid.setcolumn(cellpanel, columnindex); grid.setrow(cellpanel, rowindex); multiview.originalgrid.children.add(cellpanel); num++; } } } /// <summary> /// 三画面 /// </summary> public static void setmodel3() { multiview.clear(); columndefinition columndefinition1 = new columndefinition(); columndefinition columndefinition2 = new columndefinition(); columndefinition1.width = new gridlength(0.618, gridunittype.star); columndefinition2.width = new gridlength(0.382, gridunittype.star); multiview.originalgrid.columndefinitions.add(columndefinition1); multiview.originalgrid.columndefinitions.add(columndefinition2); cellpanel cellpanel = multiview.dictpanel[1]; grid.setcolumn(cellpanel, 0); multiview.originalgrid.children.add(cellpanel); for (int index1 = 0; index1 < 2; ++index1) { cellpanel = multiview.dictpanel[index1 + 2]; multiview.tempgrid1.rowdefinitions.add(new rowdefinition()); grid.setrow(cellpanel, index1); multiview.tempgrid1.children.add(cellpanel); } grid.setcolumn(multiview.tempgrid1, 1); multiview.originalgrid.children.add(multiview.tempgrid1); } /// <summary> /// 六画面 /// </summary> public static void setmodel6() { multiview.clear(); multiview.createcolumnandrow(multiview.originalgrid, 2, 2); multiview.originalgrid.columndefinitions[0].width = new gridlength(0.66, gridunittype.star); multiview.originalgrid.columndefinitions[1].width = new gridlength(0.34, gridunittype.star); multiview.originalgrid.rowdefinitions[0].height = new gridlength(0.67, gridunittype.star); multiview.originalgrid.rowdefinitions[1].height = new gridlength(0.33, gridunittype.star); cellpanel cellpanel = multiview.dictpanel[1]; grid.setcolumn(cellpanel, 0); grid.setrow(cellpanel, 0); multiview.originalgrid.children.add(cellpanel); //p2,p3 画面 grid.setcolumn(multiview.tempgrid1, 1); grid.setrow(multiview.tempgrid1, 0); for (int index = 0; index < 2; ++index) { cellpanel = multiview.dictpanel[index + 2]; multiview.tempgrid1.rowdefinitions.add(new rowdefinition()); grid.setrow(cellpanel, index); multiview.tempgrid1.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid1); //p4,p5 画面 grid.setcolumn(multiview.tempgrid2, 0); grid.setrow(multiview.tempgrid2, 1); for (int index = 0; index < 2; ++index) { cellpanel = multiview.dictpanel[index + 4]; multiview.tempgrid2.columndefinitions.add(new columndefinition()); grid.setcolumn(cellpanel, index); multiview.tempgrid2.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid2); cellpanel = multiview.dictpanel[6]; grid.setrow(cellpanel, 1); grid.setcolumn(cellpanel, 1); multiview.originalgrid.children.add(cellpanel); } /// <summary> /// 八画面 /// </summary> public static void setmodel8() { multiview.clear(); multiview.createcolumnandrow(multiview.originalgrid, 2, 2); multiview.originalgrid.columndefinitions[0].width = new gridlength(0.75, gridunittype.star); multiview.originalgrid.columndefinitions[1].width = new gridlength(0.25, gridunittype.star); multiview.originalgrid.rowdefinitions[0].height = new gridlength(0.75, gridunittype.star); multiview.originalgrid.rowdefinitions[1].height = new gridlength(0.25, gridunittype.star); cellpanel cellpanel = multiview.dictpanel[1]; grid.setcolumn(cellpanel, 0); grid.setrow(cellpanel, 0); multiview.originalgrid.children.add(cellpanel); //p2,p3,p4 画面 grid.setcolumn(multiview.tempgrid1, 1); grid.setrow(multiview.tempgrid1, 0); for (int index = 0; index < 3; ++index) { cellpanel = multiview.dictpanel[index + 2]; multiview.tempgrid1.rowdefinitions.add(new rowdefinition()); grid.setrow(cellpanel, index); multiview.tempgrid1.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid1); //p5,p6,p7 画面 grid.setcolumn(multiview.tempgrid2, 0); grid.setrow(multiview.tempgrid2, 1); for (int index = 0; index < 3; ++index) { cellpanel = multiview.dictpanel[index + 5]; multiview.tempgrid2.columndefinitions.add(new columndefinition()); grid.setcolumn(cellpanel, index); multiview.tempgrid2.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid2); cellpanel = multiview.dictpanel[8]; grid.setrow(cellpanel, 1); grid.setcolumn(cellpanel, 1); multiview.originalgrid.children.add(cellpanel); } /// <summary> /// 十画面 /// </summary> public static void setmodel10() { multiview.clear(); multiview.createcolumnandrow(multiview.originalgrid, 2, 2); multiview.originalgrid.columndefinitions[0].width = new gridlength(0.77, gridunittype.star); multiview.originalgrid.columndefinitions[1].width = new gridlength(0.23, gridunittype.star); multiview.originalgrid.rowdefinitions[0].height = new gridlength(0.8, gridunittype.star); multiview.originalgrid.rowdefinitions[1].height = new gridlength(0.2, gridunittype.star); cellpanel cellpanel = multiview.dictpanel[1]; grid.setcolumn(cellpanel, 0); grid.setrow(cellpanel, 0); multiview.originalgrid.children.add(cellpanel); //p2,p3,p4,p5 画面 grid.setcolumn(multiview.tempgrid1, 1); grid.setrow(multiview.tempgrid1, 0); for (int index = 0; index < 4; ++index) { cellpanel = multiview.dictpanel[index + 2]; multiview.tempgrid1.rowdefinitions.add(new rowdefinition()); grid.setrow(cellpanel, index); multiview.tempgrid1.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid1); //p6,p7,p8,p9 画面 grid.setcolumn(multiview.tempgrid2, 0); grid.setrow(multiview.tempgrid2, 1); for (int index = 0; index < 4; ++index) { cellpanel = multiview.dictpanel[index + 6]; multiview.tempgrid2.columndefinitions.add(new columndefinition()); grid.setcolumn(cellpanel, index); multiview.tempgrid2.children.add(cellpanel); } multiview.originalgrid.children.add(multiview.tempgrid2); cellpanel = multiview.dictpanel[10]; grid.setrow(cellpanel, 1); grid.setcolumn(cellpanel, 1); multiview.originalgrid.children.add(cellpanel); } /// <summary> /// 索引画面全屏 /// </summary> /// <param name="index">画面索引</param> public static void setfullscreen(int index) { multiview.clear(); cellpanel cellpanel = multiview.dictpanel[index]; grid.setcolumn(cellpanel, 0); grid.setrow(cellpanel, 0); multiview.originalgrid.children.add(cellpanel); } private static void clear() { multiview.originalgrid.rowdefinitions.clear(); multiview.originalgrid.columndefinitions.clear(); multiview.originalgrid.children.clear(); multiview.tempgrid1.children.clear(); multiview.tempgrid1.rowdefinitions.clear(); multiview.tempgrid1.columndefinitions.clear(); multiview.tempgrid2.children.clear(); multiview.tempgrid2.rowdefinitions.clear(); multiview.tempgrid2.columndefinitions.clear(); } private static void createcolumnandrow(grid grid, int row, int column) { for (int index = 0; index < row; ++index) { grid.rowdefinitions.add(new rowdefinition()); } for (int index = 0; index < column; ++index) { grid.columndefinitions.add(new columndefinition()); } } }
2、 实现单通道画面控件cellpanel
1) 前台页面
<usercontrol x:class="multiviewcontrol.cellpanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wfi="clr-namespace:system.windows.forms.integration;assembly=windowsformsintegration" xmlns:wf="clr-namespace:system.windows.forms;assembly=system.windows.forms" borderthickness="1" borderbrush="silver"> <grid background="black"> <wfi:windowsformshost > <wf:panel x:name="panel" autosize="true" dock="fill"/> </wfi:windowsformshost> </grid> </usercontrol>
2) 后台实现
1 public partial class cellpanel : system.windows.controls.usercontrol 2 { 3 public int index; 4 public bool selected; 5 6 private bool isfull = false; 7 private solidcolorbrush selectedcolor = new solidcolorbrush(colors.yellowgreen); 8 private solidcolorbrush mouseentercolor = new solidcolorbrush(colors.red); 9 private solidcolorbrush normalcolor = new solidcolorbrush(colors.silver); 10 11 public cellpanel() 12 { 13 this.initializecomponent(); 14 this.panel.click += new eventhandler(this.panel_click); 15 this.panel.doubleclick += new eventhandler(this.panel_doubleclick); 16 this.panel.mouseenter += new eventhandler(this.panel_mouseenter); 17 this.panel.mouseleave += new eventhandler(this.panel_mouseleave); 18 this.panel.sizechanged += new eventhandler(this.panel_sizechange); 19 this.selected = false; 20 } 21 22 public void panel_click(object sender, eventargs e) 23 { 24 foreach (cellpanel cellpanel in multiview.dictpanel.values) 25 { 26 cellpanel.selected = false; 27 cellpanel.borderbrush = normalcolor; 28 } 29 this.selected = true; 30 this.borderbrush = selectedcolor; 31 } 32 public void panel_doubleclick(object sender, eventargs e) 33 { 34 if (this.isfull) 35 { 36 multiview.setcurrentmodel(multiview.currentmodel); 37 } 38 else 39 { 40 multiview.setfullscreen(this.index); 41 } 42 43 this.isfull = !this.isfull; 44 } 45 private void panel_mouseenter(object sender, eventargs e) 46 { 47 if (!this.selected) 48 { 49 this.borderbrush = mouseentercolor; 50 } 51 } 52 53 private void panel_mouseleave(object sender, eventargs e) 54 { 55 if (!this.selected) 56 { 57 this.borderbrush = normalcolor; 58 } 59 } 60 private void panel_sizechange(object sender, eventargs e) 61 { 62 this.panel.size = new system.drawing.size((int)this.width - 2, (int)this.height - 2); 63 } 64 65 }
3、新建一个窗体mainwindow,调用mutiview类
1) 前台页面
1 <window x:class="multiviewcontrol.mainwindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 title="mainwindow" height="350" width="525"> 5 <grid> 6 <grid.rowdefinitions> 7 <rowdefinition height="*" /> 8 <rowdefinition height="40" /> 9 </grid.rowdefinitions> 10 <grid x:name="grid" /> 11 <stackpanel orientation="horizontal" grid.row="1"> 12 <button content="1画 面" tag="1" click="btn_click" margin="6" width="60"/> 13 <button content="3画 面" tag="3" click="btn_click" margin="6" width="60"/> 14 <button content="4画 面" tag="4" click="btn_click" margin="6" width="60"/> 15 <button content="6画 面" tag="6" click="btn_click" margin="6" width="60"/> 16 <button content="8画 面" tag="8" click="btn_click" margin="6" width="60"/> 17 <button content="9画 面" tag="9" click="btn_click" margin="6" width="60"/> 18 <button content="10画 面" tag="10" click="btn_click" margin="6" width="60"/> 19 </stackpanel> 20 </grid> 21 </window>
2) 后台实现
1 public partial class mainwindow : window 2 { 3 public mainwindow() 4 { 5 initializecomponent(); 6 multiview.initgrid(this.grid, 64); 7 multiview.setcurrentmodel(4); 8 } 9 10 private void btn_click(object sender, routedeventargs e) 11 { 12 button btn = sender as button; 13 int index = 0; 14 if(btn.tag != null) 15 { 16 multiview.setcurrentmodel(convert.toint32( btn.tag)); 17 } 18 19 } 20 21 }
多画面切换就ok了!希望能对大家有用!
上一篇: 吃鸡“神器”红辣椒7X发布,联发科P10真的能流畅..
下一篇: 爬虫学习day1