欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用WPF制作视频监控多画面切换

程序员文章站 2022-07-09 20:32:14
前言 曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用WPF开发的,所以当时就做了一个多画面切换组件,效果如下: 功能设计前提: 由于要使用海康大华天地伟业等视频厂家的视频,对接的方式是通过各个厂家提供的SDK(官网下载),由于播放视频的时候需要传递控 ......

  前言

      曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用wpf开发的,所以当时就做了一个多画面切换组件,效果如下:

使用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了!希望能对大家有用!