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

 前言

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

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

  功能设计前提:

  由于要使用海康大华天地伟业等视频厂家的视频,对接的方式是通过各个厂家提供的SDK(官网下载),由于播放视频的时候需要传递控件的句柄(Handle),所以要在WPF中使用System.Windows.Forms下的控件Panel

  具体实现:

  1、  实现多画面类MultiView,主要提供页面初始化、设置当前画面等功能

使用WPF制作视频监控多画面切换
  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());
            }      
        }
    }
使用WPF制作视频监控多画面切换

 

       2、 实现单通道画面控件CellPanel

        1) 前台页面

使用WPF制作视频监控多画面切换
<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>
使用WPF制作视频监控多画面切换

 

        2) 后台实现

使用WPF制作视频监控多画面切换
 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     }
使用WPF制作视频监控多画面切换

 

  3、新建一个窗体MainWindow,调用MutiView类

     1) 前台页面

使用WPF制作视频监控多画面切换
 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>
使用WPF制作视频监控多画面切换

 

         2) 后台实现    

使用WPF制作视频监控多画面切换
 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     }
使用WPF制作视频监控多画面切换

 

 转自:https://www.cnblogs.com/jared-an/p/10049662.html

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

上一篇:C# 从url获取get参数键值对


下一篇:WPF 中ContextMenu 在mvvm模式中的绑定问题