前言
曾有做过一个产品,有一个功能是视频监控模块,视频监控首先想到的是视频多画面切换功能,由于前端是用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
