WPF中如何实现PictureBox全屏显示(视频预览场景)
嘿,我来帮你搞定WPF里嵌套PictureBox实现视频全屏的问题!因为你是用WindowsFormsHost把WinForms的PictureBox嵌入到WPF界面中,所以得结合WPF窗口控制和WinForms控件的布局逻辑来实现,具体步骤如下:
WPF中实现PictureBox视频全屏显示方案
步骤1:完善XAML布局
首先给你的WindowsFormsHost加个命名,方便后台代码访问;再添一个全屏触发按钮:
<!-- 给WindowsFormsHost添加x:Name --> <WindowsFormsHost x:Name="videoWinFormsHost" Grid.Row="3" Grid.Column="4" Grid.ColumnSpan="2" Grid.RowSpan="2" Background="Black"> <wf:PictureBox BorderStyle="FixedSingle" x:Name="pictureBox1"/> </WindowsFormsHost> <!-- 添加全屏按钮,放在你觉得合适的布局位置 --> <Button x:Name="btnToggleFullScreen" Content="全屏" Click="BtnToggleFullScreen_Click" Margin="10"/>
步骤2:后台代码实现全屏/退出全屏逻辑
先定义变量保存原本的窗口和布局状态,避免退出全屏时界面混乱:
// 保存窗口原本的状态与边界 private WindowState _originalWindowState; private Rect _originalWindowBounds; // 保存WindowsFormsHost原来的布局参数 private int _originalColSpan; private int _originalRowSpan; private GridLength _originalRowHeight; private GridLength _originalColWidth;
然后写按钮点击事件的处理逻辑,分全屏和退出全屏两种场景:
private void BtnToggleFullScreen_Click(object sender, RoutedEventArgs e) { var parentGrid = (Grid)videoWinFormsHost.Parent; // 判断当前是否处于全屏状态 if (WindowState == WindowState.Maximized && WindowStyle == WindowStyle.None) { // 退出全屏:恢复窗口与布局 WindowState = _originalWindowState; WindowStyle = WindowStyle.SingleBorderWindow; Left = _originalWindowBounds.Left; Top = _originalWindowBounds.Top; Width = _originalWindowBounds.Width; Height = _originalWindowBounds.Height; // 把WindowsFormsHost放回原来的Grid位置 Grid.SetRow(videoWinFormsHost, 3); Grid.SetColumn(videoWinFormsHost, 4); Grid.SetColumnSpan(videoWinFormsHost, _originalColSpan); Grid.SetRowSpan(videoWinFormsHost, _originalRowSpan); // 恢复Grid的行高与列宽 parentGrid.RowDefinitions[3].Height = _originalRowHeight; parentGrid.ColumnDefinitions[4].Width = _originalColWidth; // 恢复PictureBox的显示模式 pictureBox1.Dock = DockStyle.None; pictureBox1.SizeMode = PictureBoxSizeMode.Normal; btnToggleFullScreen.Content = "全屏"; } else { // 进入全屏:先保存当前状态 _originalWindowState = WindowState; _originalWindowBounds = new Rect(Left, Top, Width, Height); _originalColSpan = Grid.GetColumnSpan(videoWinFormsHost); _originalRowSpan = Grid.GetRowSpan(videoWinFormsHost); _originalRowHeight = parentGrid.RowDefinitions[3].Height; _originalColWidth = parentGrid.ColumnDefinitions[4].Width; // 设置窗口为无边框全屏 WindowState = WindowState.Maximized; WindowStyle = WindowStyle.None; // 让WindowsFormsHost占满整个Grid Grid.SetRow(videoWinFormsHost, 0); Grid.SetColumn(videoWinFormsHost, 0); Grid.SetColumnSpan(videoWinFormsHost, parentGrid.ColumnDefinitions.Count); Grid.SetRowSpan(videoWinFormsHost, parentGrid.RowDefinitions.Count); // 让Grid的所有行和列均匀占满空间 foreach (var rowDef in parentGrid.RowDefinitions) { rowDef.Height = new GridLength(1, GridUnitType.Star); } foreach (var colDef in parentGrid.ColumnDefinitions) { colDef.Width = new GridLength(1, GridUnitType.Star); } // 让PictureBox填满整个WindowsFormsHost pictureBox1.Dock = DockStyle.Fill; pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; // 视频拉伸适配全屏 btnToggleFullScreen.Content = "退出全屏"; } }
步骤3:添加ESC快捷键退出全屏(可选)
为了提升用户体验,可以添加ESC键退出全屏的功能,重写窗口的OnKeyDown方法:
protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); // 如果当前是全屏状态,按ESC直接退出 if (e.Key == Key.Escape && WindowState == WindowState.Maximized && WindowStyle == WindowStyle.None) { BtnToggleFullScreen_Click(null, null); } }
注意事项
- 如果你用的是第三方视频播放控件(比如基于DirectShow/FFmpeg的WinForms播放控件),可能需要额外调用控件自身的全屏方法,或者确保渲染上下文能适配新的大小,避免出现黑屏、画面错位等问题
- 测试时要验证窗口状态恢复是否正常,比如原本窗口是正常大小还是最大化,退出全屏后要准确回到初始状态
内容的提问来源于stack exchange,提问作者JINESH
相关产品推荐
相关产品推荐

