前言
接着上周写的截图控件继续更新 绘制方框与椭圆。
1.WPF实现截屏「仿微信」
2.WPF 实现截屏控件之移动(二)「仿微信」
3.WPF 截图控件之伸缩(三) 「仿微信」
正文
有开发者在B站反馈第三篇有Issues已修复。

实现在截图区域内绘制 方框与椭圆 有两种方式
1)可以在截图的区域内部添加一个Canvas宽高填充至区域内,在进行绘制方框或椭圆。
2)直接在外层的Canvas中添加,这样需要判断鼠标按下的位置和移动的位置必须在已截图区域内,如超出范围也不绘制到区域外。
本章使用了第二种方式
此篇更新截图时隐藏当前窗口
一、首先接着ScreenCut继续发电。
1.1
新增定义 画方框、椭圆、颜色选择框Popup、Popup内部Border、Border内部RadioButton的父容器- [TemplatePart(Name = RadioButtonRectangleTemplateName, Type = typeof(RadioButton))]
- [TemplatePart(Name = RadioButtonEllipseTemplateName, Type = typeof(RadioButton))]
- [TemplatePart(Name = PopupTemplateName, Type = typeof(Popup))]
- [TemplatePart(Name = PopupBorderTemplateName, Type = typeof(Border))]
- [TemplatePart(Name = WrapPanelColorTemplateName, Type = typeof(WrapPanel))]
-
- private const string RadioButtonRectangleTemplateName = "PART_RadioButtonRectangle";
- private const string RadioButtonEllipseTemplateName = "PART_RadioButtonEllipse";
- private const string PopupTemplateName = "PART_Popup";
- private const string PopupBorderTemplateName = "PART_PopupBorder";
- private const string WrapPanelColorTemplateName = "PART_WrapPanelColor";
- private Popup _popup;
- private WrapPanel _wrapPanel;
-
- /// <summary>
- /// 当前绘制矩形
- /// </summary>
- private Border borderRectangle;
- /// <summary>
- /// 绘制当前椭圆
- /// </summary>
- private Ellipse drawEllipse;
- /// <summary>
- /// 当前选择颜色
- /// </summary>
- private Brush _currentBrush;
复制代码 1.2
新增RadioButtonStyles为了选择方框、椭圆、颜色- <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary>
复制代码 1.3
ScreenCut.xaml增加代码如下二、ScreenCut.cs 增加的后台逻辑如下
2.1 RadioButton选中方框和椭圆的切换Popup并设置ScreenCutMouseType枚举和鼠标:- _radioButtonRectangle = GetTemplateChild(RadioButtonRectangleTemplateName) as RadioButton;
- if (_radioButtonRectangle != null)
- _radioButtonRectangle.Click += _radioButtonRectangle_Click;
- _radioButtonEllipse = GetTemplateChild(RadioButtonEllipseTemplateName) as RadioButton;
- if (_radioButtonEllipse != null)
- _radioButtonEllipse.Click += _radioButtonEllipse_Click;
- private void _radioButtonRectangle_Click(object sender, RoutedEventArgs e)
- {
- RadioButtonChecked(_radioButtonRectangle, ScreenCutMouseType.DrawRectangle);
- }
- private void _radioButtonEllipse_Click(object sender, RoutedEventArgs e)
- {
- RadioButtonChecked(_radioButtonEllipse, ScreenCutMouseType.DrawEllipse);
- }
- void RadioButtonChecked(RadioButton radioButton, ScreenCutMouseType screenCutMouseTypeRadio)
- {
- if (radioButton.IsChecked == true)
- {
- screenCutMouseType = screenCutMouseTypeRadio;
- _border.Cursor = Cursors.Arrow;
- if (_popup.PlacementTarget != null && _popup.IsOpen)
- _popup.IsOpen = false;
- _popup.PlacementTarget = radioButton;
- _popup.IsOpen = true;
- }
- else
- {
- if (screenCutMouseType == screenCutMouseTypeRadio)
- Restore();
- }
- }
- void Restore()
- {
- _border.Cursor = Cursors.SizeAll;
- if (screenCutMouseType == ScreenCutMouseType.Default) return;
- screenCutMouseType = ScreenCutMouseType.Default;
- }
复制代码 2.2 ScreenCut绘制方框和椭圆代码如下:- void DrawMultipleControl(Point current) { if (current == pointStart) return;<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> if (current.X > rect.BottomRight.X || current.Y > rect.BottomRight.Y) return; var drawRect = new Rect(pointStart, current); switch (screenCutMouseType) { case ScreenCutMouseType.DrawRectangle: if (borderRectangle == null) {<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> borderRectangle = new Border()<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> {<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> BorderBrush = _currentBrush == null ? Brushes.Red : _currentBrush,<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> BorderThickness = new Thickness(3),<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> CornerRadius = new CornerRadius(3),<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> };<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> _canvas.Children.Add(borderRectangle); } break; case ScreenCutMouseType.DrawEllipse: if (drawEllipse == null) {<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> drawEllipse = new Ellipse()<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> {<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> Stroke = _currentBrush == null ? Brushes.Red : _currentBrush,<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> StrokeThickness = 3,<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> };<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> _canvas.Children.Add(drawEllipse); } break;<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> }<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> var _borderLeft = drawRect.Left - Canvas.GetLeft(_border);<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> if (_borderLeft < 0) _borderLeft = Math.Abs(_borderLeft); if (drawRect.Width + _borderLeft < _border.ActualWidth) { var wLeft = Canvas.GetLeft(_border) + _border.ActualWidth; var left = drawRect.Left < Canvas.GetLeft(_border) ? Canvas.GetLeft(_border) : drawRect.Left > wLeft ? wLeft : drawRect.Left; if (borderRectangle != null) { borderRectangle.Width = drawRect.Width; Canvas.SetLeft(borderRectangle, left); } if (drawEllipse != null) { drawEllipse.Width = drawRect.Width; Canvas.SetLeft(drawEllipse, left); }<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> }<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
- </ResourceDictionary.MergedDictionaries>
-
-
- </ResourceDictionary> var _borderTop = drawRect.Top - Canvas.GetTop(_border); if(_borderTop < 0) _borderTop = Math.Abs(_borderTop); if (drawRect.Height + _borderTop < _border.ActualHeight) { var hTop = Canvas.GetTop(_border) + _border.Height; var top = drawRect.Top < Canvas.GetTop(_border) ? Canvas.GetTop(_border) : drawRect.Top > hTop ? hTop : drawRect.Top; if (borderRectangle != null) { borderRectangle.Height = drawRect.Height; Canvas.SetTop(borderRectangle, top); } if (drawEllipse != null) { drawEllipse.Height = drawRect.Height; Canvas.SetTop(drawEllipse, top); } } }
复制代码 2.3 Popup跟随问题这里解决办法是先关闭再打开代码如下:- if (_popup != null && _popup.IsOpen)
- {
- _popup.IsOpen = false;
- _popup.IsOpen = true;
- }
复制代码 2.4 ScreenCut使用方式如下:- public partial class ScreenCutExample : UserControl
- {
- public bool IsChecked
- {
- get { return (bool)GetValue(IsCheckedProperty); }
- set { SetValue(IsCheckedProperty, value); }
- }
- public static readonly DependencyProperty IsCheckedProperty =
- DependencyProperty.Register("IsChecked", typeof(bool), typeof(ScreenCutExample), new PropertyMetadata(false));
- public ScreenCutExample()
- {
- InitializeComponent();
- }
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- var screenCut = new ScreenCut();
- if (IsChecked)
- {
- App.CurrentMainWindow.WindowState = WindowState.Minimized;
- screenCut.Show();
- screenCut.Activate();
- }
- else
- screenCut.ShowDialog();
- }
- }
复制代码 完整代码如下

项目地址
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |