項目案例:WPF使用WindowsFormsHost播放視頻,視頻上顯示邊框、字幕等特效;html
難點問題canvas
一、WindowsFormsHost不支持背景透明;ui
二、WPF Panel.ZIndex無效,WindowsFormsHost更優先;spa
三、使用Show打開兩個窗口,數據同步延時orm
解決方案:視頻
使用Popup,解決最頂層、解決背景透明htm
使用Canvas,解決元素拖拽blog
XAML事件
<ctrl:uiPopup x:Name="canvas" VerticalOffset="-410" IsOpen="True" AllowsTransparency="True" PopupAnimation="Fade"> <Canvas Height="410" Width="548"> <Image x:Name="PanelLeft" Height="410" Width="45" Canvas.Left="0"></Image> <Image x:Name="PanelTop" Height="45" Width="548" Canvas.Top="0"></Image> <Image x:Name="PanelRight" Height="410" Width="45" Canvas.Right="0"></Image> <Image x:Name="PanelBottom" Height="45" Width="548" Canvas.Bottom="0"></Image> <Image x:Name="PanelPlus" Height="100" Width="100" Panel.ZIndex="1"></Image> </Canvas> </ctrl:uiPopup>
ctrl:uiPopup控件,參考: 自定義WPF Popup控件 ci
C#
//註冊移動事件 PanelPlus.MouseLeftButtonDown += rectOne_MouseLeftButtonDown; PanelPlus.MouseLeftButtonUp += rectOne_MouseLeftButtonUp; PanelPlus.MouseMove += rectOne_MouseMove;
bool enableMove = false; double spanLeft = 0; double spanTop = 0; //鼠標移動 private void rectOne_MouseMove(object sender, MouseEventArgs e) { if (enableMove) { var cLeft = e.GetPosition(canvas).X - spanLeft; var cTop = e.GetPosition(canvas).Y - spanTop; //設置矩形的位置 Canvas.SetLeft(PanelPlus, cLeft); Canvas.SetTop(PanelPlus, cTop); } } //鼠標鬆開 private void rectOne_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { //釋放鼠標捕獲 PanelPlus.ReleaseMouseCapture(); enableMove = false; } //鼠標按下 private void rectOne_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var y = Convert.ToDouble(e.GetPosition(canvas).Y); y = Utils.IsNumber(y) ? y : 0; var x = Convert.ToDouble(e.GetPosition(canvas).X); x = Utils.IsNumber(x) ? x : 0; //建立鼠標捕獲 Mouse.Capture(PanelPlus); double l = Convert.ToDouble(Canvas.GetLeft(PanelPlus)); l = Utils.IsNumber(l) ? l : 0; double t = Convert.ToDouble(Canvas.GetTop(PanelPlus)); t = Utils.IsNumber(t) ? t : 0; spanLeft = x - l; spanTop = y - t; enableMove = true; }
public class Utils { //判斷字符串是否爲純數字 public static bool IsNumber(object str) { if (str == null) return false; ASCIIEncoding ascii = new ASCIIEncoding(); byte[] bytestr = ascii.GetBytes(str.ToString()); foreach (byte c in bytestr) { if (c < 48 || c > 57) { return false; } } return true; } }