1. 先“上菜”再講做法:——上圖~~
2. 動态Panel
/// <summary>
/// 動态建立面闆
/// </summary>
/// <param name="xy">Panel的XY坐标</param>
/// <param name="wh">Panel的大小</param>
private Panel CreatePanel(Point xy, Size wh)
{
Panel panel = new Panel();
panel.BackColor = System.Drawing.Color.Transparent;
panel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
panel.Location = xy;
panel.Name = string.Concat("pVideo");
panel.Size = wh;
panel.TabIndex = 0;
panel.BackColor = Color.Black;
return panel;
}
3. 分屏算法
/// 根據通道數動态計算Panel的坐标和大小
/// </summary>
/// <param name="channelCount">通道數</param>
/// <param name="xy">傳回運算後每個Panel的坐标</param>
/// <param name="wh">傳回運算後每個Panel的大小</param>
private void MathDynamicPanel(int channelCount, out Point[] xy, out Size[] wh)
xy = new Point[channelCount];
wh = new Size[channelCount];
//第一個Panel的起始坐标——不變
xy[0] = new Point(2, 38);
//模數
int modulo;
if (channelCount <= 4)
modulo = 2;
else if (channelCount <= 9)
modulo = 3;
else if (channelCount <= 16)
modulo = 4;
else if (channelCount <= 25)
modulo = 5;
else if (channelCount <= 36)
modulo = 6;
else if (channelCount <= 49)
modulo = 7;
else// if (channelCount <= 64)
modulo = 8;
int width, height;
//610 為整個預覽區的寬
width = (610 - modulo * 1) / modulo;
//532 為整個預覽區的高
height = (532 - modulo * 1) / modulo;
for (int i = 0; i < channelCount; i++)
{
wh[i] = new Size(width, height);
if (i > 0)
{
//同一行的Y坐标相等
//同一列的X坐标相等
if (i % modulo == 0)
xy[i] = new Point(xy[i - modulo].X, xy[i - modulo].Y + height + 1);
else
xy[i] = new Point(xy[i - 1].X + width + 1, xy[i - 1].Y);
}
}
代碼說明:
a). 采用平方算法,即4個頭4個Panel(2 ^ 2),8個頭9個Panel(3 ^ 3),算是比較簡單也滿足基本需求的算法了。
b). 注意需要固定左上角頂點坐标和總面積,即(2,38)和610,532,這個可以根據自己的時間情況加以修改,可以定義成const int 就行。
c). 注意裡面算坐标的時候有+1,這個是Panel之間的間隙。
4. 使用例子
在Form_Load中加入如下代碼:
Point[] xy;
Size[] wh;
int channel = 8;
//計算面闆坐标
MathDynamicPanel(channel, out xy, out wh);
//建立面闆
for (int i = 0; i < channel; i++)
this.Controls.Add(CreatePanel(xy[i], wh[i]));
運作即可見到截圖中的樣子,最大支援64個螢幕,滿足基本需求,自己加上放大、縮小和全屏的代碼功能就比較完整了。
5.文章更新維護
5.1 2010-5-22 修改一下方法,更加好用點
/// 計算視訊面闆位置和面積
/// <param name="channelCount"></param>
/// <param name="TotalSquare">總面積和坐标</param>
/// <returns></returns>
private IList<Rectangle> CalcPanelRectangle(int channelCount, Size TotalArea)
IList<Rectangle> result = new List<Rectangle>();
else if (channelCount > 64)
else
modulo = (int)Math.Ceiling(Math.Sqrt(channelCount)); //平方根
//單個畫面大小
width = (TotalArea.Width - modulo * 1) / modulo;
height = (TotalArea.Height - modulo * 1) / modulo;
Rectangle rect = new Rectangle();
rect.Width = width;
rect.Height = height;
if (i % modulo == 0)
rect.X = 1;
if (i == 0)
rect.Y = 1;
rect.Y = result[i - modulo].Y + height + 1;
else
rect.X = result[i - 1].X + width + 1;
rect.Y = result[i - 1].Y;
result.Add(rect);
return result;
5.2 示例代碼 2010-5-25