前言
曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用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 }
转自:https://www.cnblogs.com/jared-an/p/10049662.html