From 76f7b5a24716da392a8d623cb036559b136f518e Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Mon, 12 Nov 2018 18:10:47 +0800 Subject: [PATCH] add imageviewer --- HandyControl/Controls/Attach/EdgeElement.cs | 3 +- .../Controls/Attach/StatusSwitchElement.cs | 3 +- HandyControl/Controls/Carousel.cs | 4 +- HandyControl/Controls/CircleProgressBar.cs | 2 +- HandyControl/Controls/Clock/Clock.cs | 2 +- HandyControl/Controls/Growl.cs | 4 +- HandyControl/Controls/ImageViewer.cs | 863 ++++++++++++++++++ HandyControl/Controls/Input/NumericUpDown.cs | 6 +- HandyControl/Controls/Input/TextBox.cs | 4 +- HandyControl/Controls/Loading/LoadingBase.cs | 3 +- HandyControl/Controls/ScrollViewer.cs | 7 +- .../Controls/TabControl/TabControl.cs | 9 +- HandyControl/Controls/TabControl/TabPanel.cs | 3 +- HandyControl/Controls/TimeBar/TimeBar.cs | 2 +- HandyControl/Controls/Window/ImageBrowser.cs | 862 +---------------- HandyControl/Controls/Window/PopupWindow.cs | 10 +- .../Controls/Window/WindowBorderless.cs | 6 +- HandyControl/HandyControl.csproj | 5 + .../Interactivity/FluidMoveBehavior.cs | 3 +- .../Interactivity/FluidMoveBehaviorBase.cs | 3 +- HandyControl/Themes/Styles/ImageViewer.xaml | 87 ++ HandyControl/Themes/Styles/Style.xaml | 1 + HandyControl/Themes/Styles/Window.xaml | 71 +- .../Controls/ImageBrowserDemoCtl.xaml | 5 +- .../UserControl/Main/LeftMainContent.xaml | 4 +- 25 files changed, 1055 insertions(+), 917 deletions(-) create mode 100644 HandyControl/Controls/ImageViewer.cs create mode 100644 HandyControl/Themes/Styles/ImageViewer.xaml diff --git a/HandyControl/Controls/Attach/EdgeElement.cs b/HandyControl/Controls/Attach/EdgeElement.cs index d43704b7..d674641b 100644 --- a/HandyControl/Controls/Attach/EdgeElement.cs +++ b/HandyControl/Controls/Attach/EdgeElement.cs @@ -1,4 +1,5 @@ using System.Windows; +using HandyControl.Data; // ReSharper disable once CheckNamespace namespace HandyControl.Controls @@ -34,7 +35,7 @@ namespace HandyControl.Controls public static object GetBottomContent(DependencyObject element) => element.GetValue(BottomContentProperty); public static readonly DependencyProperty ShowEdgeContentProperty = DependencyProperty.RegisterAttached( - "ShowEdgeContent", typeof(bool), typeof(EdgeElement), new PropertyMetadata(default(bool))); + "ShowEdgeContent", typeof(bool), typeof(EdgeElement), new PropertyMetadata(BooleanBoxes.FalseBox)); public static void SetShowEdgeContent(DependencyObject element, bool value) => element.SetValue(ShowEdgeContentProperty, value); diff --git a/HandyControl/Controls/Attach/StatusSwitchElement.cs b/HandyControl/Controls/Attach/StatusSwitchElement.cs index 1c3f3e1a..ab822d2d 100644 --- a/HandyControl/Controls/Attach/StatusSwitchElement.cs +++ b/HandyControl/Controls/Attach/StatusSwitchElement.cs @@ -1,4 +1,5 @@ using System.Windows; +using HandyControl.Data; // ReSharper disable once CheckNamespace namespace HandyControl.Controls @@ -19,7 +20,7 @@ namespace HandyControl.Controls /// 是否隐藏元素 /// public static readonly DependencyProperty HiddenElementProperty = DependencyProperty.RegisterAttached( - "HiddenElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(default(bool))); + "HiddenElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(BooleanBoxes.FalseBox)); public static void SetHiddenElement(DependencyObject element, bool value) => element.SetValue(HiddenElementProperty, value); diff --git a/HandyControl/Controls/Carousel.cs b/HandyControl/Controls/Carousel.cs index f25c2f45..3d2e7226 100644 --- a/HandyControl/Controls/Carousel.cs +++ b/HandyControl/Controls/Carousel.cs @@ -80,7 +80,7 @@ namespace HandyControl.Controls } public static readonly DependencyProperty AutoRunProperty = DependencyProperty.Register( - "AutoRun", typeof(bool), typeof(Carousel), new PropertyMetadata(default(bool), (o, args) => + "AutoRun", typeof(bool), typeof(Carousel), new PropertyMetadata(BooleanBoxes.FalseBox, (o, args) => { var ctl = (Carousel)o; ctl.TimerSwitch((bool)args.NewValue); @@ -99,7 +99,7 @@ namespace HandyControl.Controls } public static readonly DependencyProperty IsCenterProperty = DependencyProperty.Register( - "IsCenter", typeof(bool), typeof(Carousel), new PropertyMetadata(default(bool))); + "IsCenter", typeof(bool), typeof(Carousel), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool IsCenter { diff --git a/HandyControl/Controls/CircleProgressBar.cs b/HandyControl/Controls/CircleProgressBar.cs index 4f4fa5d0..261f8b56 100644 --- a/HandyControl/Controls/CircleProgressBar.cs +++ b/HandyControl/Controls/CircleProgressBar.cs @@ -14,7 +14,7 @@ namespace HandyControl.Controls "ArcThickness", typeof(double), typeof(CircleProgressBar), new PropertyMetadata(default(double))); public static readonly DependencyProperty ShowTextProperty = DependencyProperty.Register( - "ShowText", typeof(bool), typeof(CircleProgressBar), new PropertyMetadata(true)); + "ShowText", typeof(bool), typeof(CircleProgressBar), new PropertyMetadata(BooleanBoxes.TrueBox)); private Arc _indicator; diff --git a/HandyControl/Controls/Clock/Clock.cs b/HandyControl/Controls/Clock/Clock.cs index 9447c58b..9a474966 100644 --- a/HandyControl/Controls/Clock/Clock.cs +++ b/HandyControl/Controls/Clock/Clock.cs @@ -152,7 +152,7 @@ namespace HandyControl.Controls } internal static readonly DependencyProperty ShowConfirmButtonProperty = DependencyProperty.Register( - "ShowConfirmButton", typeof(bool), typeof(Clock), new PropertyMetadata(default(bool))); + "ShowConfirmButton", typeof(bool), typeof(Clock), new PropertyMetadata(BooleanBoxes.FalseBox)); internal bool ShowConfirmButton { diff --git a/HandyControl/Controls/Growl.cs b/HandyControl/Controls/Growl.cs index 3f1a5cc6..51be50ce 100644 --- a/HandyControl/Controls/Growl.cs +++ b/HandyControl/Controls/Growl.cs @@ -103,7 +103,7 @@ namespace HandyControl.Controls "ConfirmStr", typeof(string), typeof(Growl), new PropertyMetadata(default(string))); public static readonly DependencyProperty ShowDateTimeProperty = DependencyProperty.Register( - "ShowDateTime", typeof(bool), typeof(Growl), new PropertyMetadata(true)); + "ShowDateTime", typeof(bool), typeof(Growl), new PropertyMetadata(BooleanBoxes.TrueBox)); public static readonly DependencyProperty MessageProperty = DependencyProperty.Register( "Message", typeof(string), typeof(Growl), new PropertyMetadata(default(string))); @@ -121,7 +121,7 @@ namespace HandyControl.Controls "Type", typeof(InfoType), typeof(Growl), new PropertyMetadata(default(InfoType))); public static readonly DependencyProperty GrowlParentProperty = DependencyProperty.RegisterAttached( - "GrowlParent", typeof(bool), typeof(Growl), new PropertyMetadata(default(bool), (o, args) => + "GrowlParent", typeof(bool), typeof(Growl), new PropertyMetadata(BooleanBoxes.FalseBox, (o, args) => { if (o is Panel panel) { diff --git a/HandyControl/Controls/ImageViewer.cs b/HandyControl/Controls/ImageViewer.cs new file mode 100644 index 00000000..5561d63f --- /dev/null +++ b/HandyControl/Controls/ImageViewer.cs @@ -0,0 +1,863 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using HandyControl.Data; +using HandyControl.Interactivity; +using HandyControl.Properties.Langs; +using HandyControl.Tools; +using Microsoft.Win32; + +namespace HandyControl.Controls +{ + [TemplatePart(Name = ElementGridMain, Type = typeof(Grid))] + [TemplatePart(Name = ElementCanvasSmallImg, Type = typeof(Canvas))] + [TemplatePart(Name = ElementBorderMove, Type = typeof(Border))] + [TemplatePart(Name = ElementBorderBottom, Type = typeof(Border))] + [TemplatePart(Name = ElementImageMain, Type = typeof(Image))] + public class ImageViewer : Control + { + #region Constants + + private const string ElementGridMain = "PART_GridMain"; + + private const string ElementCanvasSmallImg = "PART_CanvasSmallImg"; + + private const string ElementBorderMove = "PART_BorderMove"; + + private const string ElementBorderBottom = "PART_BorderBottom"; + + private const string ElementImageMain = "PART_ImageMain"; + + /// + /// 缩放比间隔 + /// + private const double ScaleInternal = 0.2; + + #endregion Constants + + #region Data + + /// + /// 图片保存对话框 + /// + private static readonly SaveFileDialog SaveFileDialog = new SaveFileDialog + { + Filter = $"{Lang.PngImg}|*.png" + }; + + private Grid _gridMain; + + private Canvas _canvasSmallImg; + + private Border _borderMove; + + private Border _borderBottom; + + private Image _imageMain; + + /// + /// 右下角小图片是否加载过 + /// + private bool _borderSmallIsLoaded; + + /// + /// 图片是否可以在x轴方向移动 + /// + private bool _canMoveX; + + /// + /// 图片是否可以在y轴方向移动 + /// + private bool _canMoveY; + + /// + /// 图片实际位置 + /// + private Thickness _imgActualMargin; + + /// + /// 图片实际旋转角度 + /// + private double _imgActualRotate; + + /// + /// 图片实际旋缩放比 + /// + private double _imgActualScale = 1; + + /// + /// 在图片上鼠标移动时的即时位置 + /// + private Point _imgCurrentPoint; + + /// + /// 鼠标是否在图片上按下左键 + /// + private bool _imgIsMouseLeftButtonDown; + + /// + /// 在图片上按下时图片的位置 + /// + private Thickness _imgMouseDownMargin; + + /// + /// 在图片上按下时鼠标的位置 + /// + private Point _imgMouseDownPoint; + + /// + /// 在小图片上鼠标移动时的即时位置 + /// + private Point _imgSmallCurrentPoint; + + /// + /// 鼠标是否在小图片上按下左键 + /// + private bool _imgSmallIsMouseLeftButtonDown; + + /// + /// 在小图片上按下时图片的位置 + /// + private Thickness _imgSmallMouseDownMargin; + + /// + /// 在小图片上按下时鼠标的位置 + /// + private Point _imgSmallMouseDownPoint; + + /// + /// 图片长宽比 + /// + private double _imgWidHeiScale; + + /// + /// 是否已经初始化 + /// + private bool _isLoaded; + + /// + /// 图片是否倾斜 + /// + private bool _isOblique; + + /// + /// 缩放高度间隔 + /// + private double _scaleInternalHeight; + + /// + /// 缩放宽度间隔 + /// + private double _scaleInternalWidth; + + /// + /// 底部BorderBottom(包含一些图片操作)是否显示中 + /// + private bool _showBorderBottom; + + #endregion Data + + #region ctor + + public ImageViewer() + { + Loaded += ImageViewer_OnLoaded; + + CommandBindings.Add(new CommandBinding(ControlCommands.Save, ButtonSave_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.Open, ButtonWindowsOpen_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.Restore, ButtonActual_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.Reduce, ButtonReduce_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.Enlarge, ButtonEnlarge_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.RotateLeft, ButtonRotateLeft_OnClick)); + CommandBindings.Add(new CommandBinding(ControlCommands.RotateRight, ButtonRotateRight_OnClick)); + } + + /// + /// 带一个图片Uri的构造函数 + /// + /// + public ImageViewer(Uri uri) : this() + { + try + { + ImageSource = BitmapFrame.Create(uri); + ImgPath = uri.AbsolutePath; + if (File.Exists(ImgPath)) + { + var info = new FileInfo(ImgPath); + ImgSize = info.Length; + } + } + catch + { + PopupWindow.ShowDialog(Lang.ErrorImgPath); + } + } + + /// + /// 带一个图片路径的构造函数 + /// + /// + public ImageViewer(string path) : this(new Uri(path)) + { + } + + #endregion + + #region Properties + + public static readonly DependencyProperty ShowImgMapProperty = DependencyProperty.Register( + "ShowImgMap", typeof(bool), typeof(ImageViewer), new PropertyMetadata(BooleanBoxes.FalseBox)); + + public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register( + "ImageSource", typeof(BitmapFrame), typeof(ImageViewer), new PropertyMetadata(default(BitmapFrame))); + + internal static readonly DependencyProperty ImgPathProperty = DependencyProperty.Register( + "ImgPath", typeof(string), typeof(ImageViewer), new PropertyMetadata(default(string))); + + internal static readonly DependencyProperty ImgSizeProperty = DependencyProperty.Register( + "ImgSize", typeof(long), typeof(ImageViewer), new PropertyMetadata(-1L)); + + /// + /// 是否显示全屏按钮 + /// + internal static readonly DependencyProperty ShowFullScreenButtonProperty = DependencyProperty.Register( + "ShowFullScreenButton", typeof(bool), typeof(ImageViewer), new PropertyMetadata(BooleanBoxes.FalseBox)); + + /// + /// 关闭按钮是否显示中 + /// + internal static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.Register( + "ShowCloseButton", typeof(bool), typeof(ImageViewer), new PropertyMetadata(BooleanBoxes.FalseBox)); + + internal static readonly DependencyProperty ImageContentProperty = DependencyProperty.Register( + "ImageContent", typeof(object), typeof(ImageViewer), new PropertyMetadata(default(object))); + + internal static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register( + "ImageMargin", typeof(Thickness), typeof(ImageViewer), new PropertyMetadata(default(Thickness))); + + internal static readonly DependencyProperty ImageWidthProperty = DependencyProperty.Register( + "ImageWidth", typeof(double), typeof(ImageViewer), new PropertyMetadata(default(double))); + + internal static readonly DependencyProperty ImageHeightProperty = DependencyProperty.Register( + "ImageHeight", typeof(double), typeof(ImageViewer), new PropertyMetadata(default(double))); + + internal static readonly DependencyProperty ImageScaleProperty = DependencyProperty.Register( + "ImageScale", typeof(double), typeof(ImageViewer), new PropertyMetadata(1.0, OnImageScaleChanged)); + + internal static readonly DependencyProperty ScaleStrProperty = DependencyProperty.Register( + "ScaleStr", typeof(string), typeof(ImageViewer), new PropertyMetadata("100%")); + + internal static readonly DependencyProperty ImageRotateProperty = DependencyProperty.Register( + "ImageRotate", typeof(double), typeof(ImageViewer), new PropertyMetadata(default(double))); + + internal static readonly DependencyProperty ShowSmallImgInternalProperty = DependencyProperty.Register( + "ShowSmallImgInternal", typeof(bool), typeof(ImageViewer), new PropertyMetadata(false)); + + public bool ShowImgMap + { + get => (bool)GetValue(ShowImgMapProperty); + set => SetValue(ShowImgMapProperty, value); + } + + public BitmapFrame ImageSource + { + get => (BitmapFrame)GetValue(ImageSourceProperty); + set => SetValue(ImageSourceProperty, value); + } + + internal object ImageContent + { + get => GetValue(ImageContentProperty); + set => SetValue(ImageContentProperty, value); + } + + internal string ImgPath + { + get => (string)GetValue(ImgPathProperty); + set => SetValue(ImgPathProperty, value); + } + + internal long ImgSize + { + get => (long)GetValue(ImgSizeProperty); + set => SetValue(ImgSizeProperty, value); + } + + /// + /// 是否显示全屏按钮 + /// + internal bool ShowFullScreenButton + { + get => (bool)GetValue(ShowFullScreenButtonProperty); + set => SetValue(ShowFullScreenButtonProperty, value); + } + + internal Thickness ImageMargin + { + get => (Thickness)GetValue(ImageMarginProperty); + set => SetValue(ImageMarginProperty, value); + } + + internal double ImageWidth + { + get => (double)GetValue(ImageWidthProperty); + set => SetValue(ImageWidthProperty, value); + } + + internal double ImageHeight + { + get => (double)GetValue(ImageHeightProperty); + set => SetValue(ImageHeightProperty, value); + } + + internal double ImageScale + { + get => (double)GetValue(ImageScaleProperty); + set => SetValue(ImageScaleProperty, value); + } + + internal string ScaleStr + { + get => (string)GetValue(ScaleStrProperty); + set => SetValue(ScaleStrProperty, value); + } + + internal double ImageRotate + { + get => (double)GetValue(ImageRotateProperty); + set => SetValue(ImageRotateProperty, value); + } + + internal bool ShowSmallImgInternal + { + get => (bool)GetValue(ShowSmallImgInternalProperty); + set => SetValue(ShowSmallImgInternalProperty, value); + } + + /// + /// 图片原始宽度 + /// + private double ImageOriWidth { get; set; } + + /// + /// 图片原始高度 + /// + private double ImageOriHeight { get; set; } + + /// + /// 关闭按钮是否显示中 + /// + internal bool ShowCloseButton + { + get => (bool)GetValue(ShowCloseButtonProperty); + set => SetValue(ShowCloseButtonProperty, value); + } + + /// + /// 底部BorderBottom(包含一些图片操作)是否显示中 + /// + internal bool ShowBorderBottom + { + get => _showBorderBottom; + set + { + if (_showBorderBottom == value) return; + _borderBottom?.BeginAnimation(OpacityProperty, + value ? AnimationHelper.CreateAnimation(1, 100) : AnimationHelper.CreateAnimation(0, 400)); + _showBorderBottom = value; + } + } + + #endregion + + public override void OnApplyTemplate() + { + if (_imageMain != null) _imageMain.MouseLeftButtonDown -= ImageMain_OnMouseLeftButtonDown; + + if (_canvasSmallImg != null) + { + _canvasSmallImg.MouseLeftButtonDown -= CanvasSmallImg_OnMouseLeftButtonDown; + _canvasSmallImg.MouseLeftButtonUp -= CanvasSmallImg_OnMouseLeftButtonUp; + _canvasSmallImg.MouseMove -= CanvasSmallImg_OnMouseMove; + _canvasSmallImg.MouseLeave -= CanvasSmallImg_OnMouseLeave; + } + + base.OnApplyTemplate(); + + _gridMain = GetTemplateChild(ElementGridMain) as Grid; + _canvasSmallImg = GetTemplateChild(ElementCanvasSmallImg) as Canvas; + _borderMove = GetTemplateChild(ElementBorderMove) as Border; + _imageMain = GetTemplateChild(ElementImageMain) as Image; + _borderBottom = GetTemplateChild(ElementBorderBottom) as Border; + + if (_imageMain != null) _imageMain.MouseLeftButtonDown += ImageMain_OnMouseLeftButtonDown; + + if (_canvasSmallImg != null) + { + _canvasSmallImg.MouseLeftButtonDown += CanvasSmallImg_OnMouseLeftButtonDown; + _canvasSmallImg.MouseLeftButtonUp += CanvasSmallImg_OnMouseLeftButtonUp; + _canvasSmallImg.MouseMove += CanvasSmallImg_OnMouseMove; + _canvasSmallImg.MouseLeave += CanvasSmallImg_OnMouseLeave; + } + } + + private static void OnImageScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is ImageViewer ImageViewer && e.NewValue is double newValue) + { + ImageViewer.ImageWidth = ImageViewer.ImageOriWidth * newValue; + ImageViewer.ImageHeight = ImageViewer.ImageOriHeight * newValue; + ImageViewer.ScaleStr = $"{newValue * 100:#0}%"; + } + } + + /// + /// 初始化 + /// + private void Init() + { + if (ImageSource == null) return; + + double width; + double height; + + if (!_isOblique) + { + width = ImageSource.Width; + height = ImageSource.Height; + } + else + { + width = ImageSource.Height; + height = ImageSource.Width; + } + + ImageWidth = width; + ImageHeight = height; + ImageOriWidth = width; + ImageOriHeight = height; + _scaleInternalWidth = ImageOriWidth * ScaleInternal; + _scaleInternalHeight = ImageOriHeight * ScaleInternal; + + if (Math.Abs(height - 0) < 0.001 || Math.Abs(width - 0) < 0.001) + { + PopupWindow.ShowDialog(Lang.ErrorImgSize); + return; + } + + _imgWidHeiScale = width / height; + var scaleWindow = ActualWidth / ActualHeight; + if (_imgWidHeiScale > scaleWindow) + { + if (width > ActualWidth) + ImageScale = ActualWidth / width; + } + else if (height > ActualHeight) + { + ImageScale = ActualHeight / height; + } + + ImageMargin = new Thickness((ActualWidth - ImageWidth) / 2, (ActualHeight - ImageHeight) / 2, 0, 0); + + _imgActualScale = 1; + _imgActualMargin = ImageMargin; + } + + private void ButtonActual_OnClick(object sender, RoutedEventArgs e) + { + var scaleAnimation = AnimationHelper.CreateAnimation(1); + scaleAnimation.FillBehavior = FillBehavior.Stop; + _imgActualScale = 1; + scaleAnimation.Completed += (s, e1) => + { + ImageScale = 1; + _canMoveX = ImageWidth > ActualWidth; + _canMoveY = ImageHeight > ActualHeight; + BorderSmallShowSwitch(); + }; + var thickness = new Thickness((ActualWidth - ImageOriWidth) / 2, (ActualHeight - ImageOriHeight) / 2, 0, 0); + var marginAnimation = AnimationHelper.CreateAnimation(thickness); + marginAnimation.FillBehavior = FillBehavior.Stop; + _imgActualMargin = thickness; + marginAnimation.Completed += (s, e1) => { ImageMargin = thickness; }; + + BeginAnimation(ImageScaleProperty, scaleAnimation); + BeginAnimation(ImageMarginProperty, marginAnimation); + } + + private void ButtonReduce_OnClick(object sender, RoutedEventArgs e) => ScaleImg(false); + + private void ButtonEnlarge_OnClick(object sender, RoutedEventArgs e) => ScaleImg(true); + + private void ButtonRotateLeft_OnClick(object sender, RoutedEventArgs e) => RotateImg(_imgActualRotate - 90); + + private void ButtonRotateRight_OnClick(object sender, RoutedEventArgs e) => RotateImg(_imgActualRotate + 90); + + private void ButtonSave_OnClick(object sender, RoutedEventArgs e) + { + if (ImageSource == null) return; + SaveFileDialog.FileName = $"{DateTime.Now:yyyy-M-d-h-m-s.fff}"; + if (SaveFileDialog.ShowDialog() == true) + { + var path = SaveFileDialog.FileName; + using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) + { + var encoder = new PngBitmapEncoder(); + encoder.Frames.Add(BitmapFrame.Create(ImageSource)); + encoder.Save(fileStream); + } + } + } + + private void ButtonWindowsOpen_OnClick(object sender, RoutedEventArgs e) + { + try + { + Process.Start(ImgPath); + } + catch (Exception exception) + { + PopupWindow.ShowDialog(exception.Message); + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + MoveImg(); + } + + protected override void OnMouseLeave(MouseEventArgs e) + { + base.OnMouseLeave(e); + _imgIsMouseLeftButtonDown = false; + ShowBorderBottom = false; + } + + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + base.OnMouseWheel(e); + ScaleImg(e.Delta > 0); + } + + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) + { + base.OnRenderSizeChanged(sizeInfo); + + if (!_isLoaded) return; + + if (ImageWidth < 0.001 || ImageHeight < 0.001) return; + + _canMoveX = true; + _canMoveY = true; + + var marginX = ImageMargin.Left; + var marginY = ImageMargin.Top; + + if (ImageWidth <= ActualWidth) + { + _canMoveX = false; + marginX = (ActualWidth - ImageWidth) / 2; + } + + if (ImageHeight <= ActualHeight) + { + _canMoveY = false; + marginY = (ActualHeight - ImageHeight) / 2; + } + + ImageMargin = new Thickness(marginX, marginY, 0, 0); + _imgActualMargin = ImageMargin; + + BorderSmallShowSwitch(); + _imgSmallMouseDownMargin = _borderMove.Margin; + MoveSmallImg(_imgSmallMouseDownMargin.Left, _imgSmallMouseDownMargin.Top); + } + + private void ImageViewer_OnLoaded(object sender, RoutedEventArgs e) + { + if (_isLoaded) return; + Init(); + _isLoaded = true; + } + + private void ImageMain_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + _imgMouseDownPoint = Mouse.GetPosition(_gridMain); + _imgMouseDownMargin = ImageMargin; + _imgIsMouseLeftButtonDown = true; + } + + protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonUp(e); + _imgIsMouseLeftButtonDown = false; + } + + /// + /// 右下角小图片显示切换 + /// + private void BorderSmallShowSwitch() + { + if (_canMoveX || _canMoveY) + { + if (!_borderSmallIsLoaded) + { + _canvasSmallImg.Background = new VisualBrush(_imageMain); + InitBorderSmall(); + _borderSmallIsLoaded = true; + } + + ShowSmallImgInternal = true; + UpdateBorderSmall(); + } + else + { + ShowSmallImgInternal = false; + } + } + + /// + /// 初始化右下角小图片 + /// + private void InitBorderSmall() + { + var scaleWindow = _canvasSmallImg.MaxWidth / _canvasSmallImg.MaxHeight; + if (_imgWidHeiScale > scaleWindow) + { + _canvasSmallImg.Width = _canvasSmallImg.MaxWidth; + _canvasSmallImg.Height = _canvasSmallImg.Width / _imgWidHeiScale; + } + else + { + _canvasSmallImg.Width = _canvasSmallImg.MaxHeight * _imgWidHeiScale; + _canvasSmallImg.Height = _canvasSmallImg.MaxHeight; + } + } + + /// + /// 更新右下角小图片 + /// + private void UpdateBorderSmall() + { + if (!ShowSmallImgInternal) return; + + var widthMin = Math.Min(ImageWidth, ActualWidth); + var heightMin = Math.Min(ImageHeight, ActualHeight); + + _borderMove.Width = widthMin / ImageWidth * _canvasSmallImg.Width; + _borderMove.Height = heightMin / ImageHeight * _canvasSmallImg.Height; + + var marginX = -ImageMargin.Left / ImageWidth * _canvasSmallImg.Width; + var marginY = -ImageMargin.Top / ImageHeight * _canvasSmallImg.Height; + + var marginXMax = _canvasSmallImg.Width - _borderMove.Width; + var marginYMax = _canvasSmallImg.Height - _borderMove.Height; + + marginX = Math.Max(0, marginX); + marginX = Math.Min(marginXMax, marginX); + marginY = Math.Max(0, marginY); + marginY = Math.Min(marginYMax, marginY); + + _borderMove.Margin = new Thickness(marginX, marginY, 0, 0); + } + + /// + /// 缩放图片 + /// + /// + private void ScaleImg(bool isEnlarge) + { + if (Mouse.LeftButton == MouseButtonState.Pressed) return; + var oldImageWidth = ImageWidth; + var olgImageHeight = ImageHeight; + + var tempScale = isEnlarge ? _imgActualScale + ScaleInternal : _imgActualScale - ScaleInternal; + if (Math.Abs(tempScale) < ScaleInternal || Math.Abs(tempScale - 50) < 0.001) + return; + + ImageScale = tempScale; + + var posCanvas = Mouse.GetPosition(_gridMain); + var posImg = new Point(posCanvas.X - _imgActualMargin.Left, posCanvas.Y - _imgActualMargin.Top); + + var marginX = .5 * _scaleInternalWidth; + var marginY = .5 * _scaleInternalHeight; + + if (ImageWidth > ActualWidth) + { + _canMoveX = true; + if (ImageHeight > ActualHeight) + { + _canMoveY = true; + marginX = posImg.X / oldImageWidth * _scaleInternalWidth; + marginY = posImg.Y / olgImageHeight * _scaleInternalHeight; + } + else + { + _canMoveY = false; + } + } + else + { + _canMoveY = ImageHeight > ActualHeight; + _canMoveX = false; + } + + Thickness thickness; + if (isEnlarge) + { + thickness = new Thickness(_imgActualMargin.Left - marginX, _imgActualMargin.Top - marginY, 0, 0); + } + else + { + var marginActualX = _imgActualMargin.Left + marginX; + var marginActualY = _imgActualMargin.Top + marginY; + var subX = ImageWidth - ActualWidth; + var subY = ImageHeight - ActualHeight; + + var right = Math.Abs(_borderMove.Width - _canvasSmallImg.ActualWidth + _borderMove.Margin.Left); + var top = Math.Abs(_borderMove.Height - _canvasSmallImg.ActualHeight + _borderMove.Margin.Top); + if (Math.Abs(ImageMargin.Left) < 0.001 || right < 0.001) + marginActualX = _imgActualMargin.Left + _borderMove.Margin.Left / + (_canvasSmallImg.ActualWidth - _borderMove.Width) * _scaleInternalWidth; + if (Math.Abs(ImageMargin.Top) < 0.001 || top < 0.001) + marginActualY = _imgActualMargin.Top + _borderMove.Margin.Top / + (_canvasSmallImg.ActualHeight - _borderMove.Height) * _scaleInternalHeight; + if (subX < 0.001) marginActualX = (ActualWidth - ImageWidth) / 2; + if (subY < 0.001) marginActualY = (ActualHeight - ImageHeight) / 2; + thickness = new Thickness(marginActualX, marginActualY, 0, 0); + } + + ImageMargin = thickness; + _imgActualScale = tempScale; + _imgActualMargin = thickness; + BorderSmallShowSwitch(); + + _imgSmallMouseDownMargin = _borderMove.Margin; + MoveSmallImg(_imgSmallMouseDownMargin.Left, _imgSmallMouseDownMargin.Top); + } + + /// + /// 旋转图片 + /// + /// + private void RotateImg(double rotate) + { + _imgActualRotate = rotate; + + _isOblique = ((int) _imgActualRotate - 90) % 180 == 0; + ShowSmallImgInternal = false; + Init(); + InitBorderSmall(); + + var animation = AnimationHelper.CreateAnimation(rotate); + animation.Completed += (s, e1) => { ImageRotate = rotate; }; + animation.FillBehavior = FillBehavior.Stop; + BeginAnimation(ImageRotateProperty, animation); + } + + /// + /// 移动图片 + /// + private void MoveImg() + { + _imgCurrentPoint = Mouse.GetPosition(_gridMain); + ShowCloseButton = _imgCurrentPoint.Y < 200; + ShowBorderBottom = _imgCurrentPoint.Y > ActualHeight - 200; + + if (_imgIsMouseLeftButtonDown) + { + var subX = _imgCurrentPoint.X - _imgMouseDownPoint.X; + var subY = _imgCurrentPoint.Y - _imgMouseDownPoint.Y; + + var marginX = _imgMouseDownMargin.Left; + if (ImageWidth > ActualWidth) + { + marginX = _imgMouseDownMargin.Left + subX; + if (marginX >= 0) + marginX = 0; + else if (-marginX + ActualWidth >= ImageWidth) marginX = ActualWidth - ImageWidth; + _canMoveX = true; + } + + var marginY = _imgMouseDownMargin.Top; + if (ImageHeight > ActualHeight) + { + marginY = _imgMouseDownMargin.Top + subY; + if (marginY >= 0) + marginY = 0; + else if (-marginY + ActualHeight >= ImageHeight) marginY = ActualHeight - ImageHeight; + _canMoveY = true; + } + + ImageMargin = new Thickness(marginX, marginY, 0, 0); + _imgActualMargin = ImageMargin; + + UpdateBorderSmall(); + } + } + + /// + /// 移动小图片 + /// + private void MoveSmallImg() + { + if (_imgSmallIsMouseLeftButtonDown) + { + _imgSmallCurrentPoint = Mouse.GetPosition(_canvasSmallImg); + + var subX = _imgSmallCurrentPoint.X - _imgSmallMouseDownPoint.X; + var subY = _imgSmallCurrentPoint.Y - _imgSmallMouseDownPoint.Y; + + var marginX = _imgSmallMouseDownMargin.Left + subX; + var marginY = _imgSmallMouseDownMargin.Top + subY; + + MoveSmallImg(marginX, marginY); + } + } + + private void MoveSmallImg(double marginX, double marginY) + { + if (marginX < 0) + marginX = 0; + else if (marginX + _borderMove.Width >= _canvasSmallImg.Width) + marginX = _canvasSmallImg.Width - _borderMove.Width; + if (marginY < 0) + marginY = 0; + else if (marginY + _borderMove.Height >= _canvasSmallImg.Height) + marginY = _canvasSmallImg.Height - _borderMove.Height; + _borderMove.Margin = new Thickness(marginX, marginY, 0, 0); + + var marginActualX = (ActualWidth - ImageWidth) / 2; + var marginActualY = (ActualHeight - ImageHeight) / 2; + + if (_canMoveX) marginActualX = -marginX / _canvasSmallImg.Width * ImageWidth; + if (_canMoveY) marginActualY = -marginY / _canvasSmallImg.Height * ImageHeight; + + ImageMargin = new Thickness(marginActualX, marginActualY, 0, 0); + _imgActualMargin = ImageMargin; + } + + private void CanvasSmallImg_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + _imgSmallMouseDownPoint = Mouse.GetPosition(_canvasSmallImg); + _imgSmallMouseDownMargin = _borderMove.Margin; + _imgSmallIsMouseLeftButtonDown = true; + e.Handled = true; + } + + private void CanvasSmallImg_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) => _imgSmallIsMouseLeftButtonDown = false; + + private void CanvasSmallImg_OnMouseMove(object sender, MouseEventArgs e) => MoveSmallImg(); + + private void CanvasSmallImg_OnMouseLeave(object sender, MouseEventArgs e) => _imgSmallIsMouseLeftButtonDown = false; + } +} \ No newline at end of file diff --git a/HandyControl/Controls/Input/NumericUpDown.cs b/HandyControl/Controls/Input/NumericUpDown.cs index 54fa7130..c76d411d 100644 --- a/HandyControl/Controls/Input/NumericUpDown.cs +++ b/HandyControl/Controls/Input/NumericUpDown.cs @@ -301,7 +301,7 @@ namespace HandyControl.Controls /// 是否显示上下调值按钮 /// internal static readonly DependencyProperty ShowUpDownButtonProperty = DependencyProperty.Register( - "ShowUpDownButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(true)); + "ShowUpDownButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(BooleanBoxes.TrueBox)); /// /// 是否显示上下调值按钮 @@ -316,7 +316,7 @@ namespace HandyControl.Controls /// 数据是否错误 /// public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register( - "IsError", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(default(bool))); + "IsError", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool IsError { @@ -352,7 +352,7 @@ namespace HandyControl.Controls /// 是否显示清除按钮 /// public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register( - "ShowClearButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(default(bool))); + "ShowClearButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool ShowClearButton { diff --git a/HandyControl/Controls/Input/TextBox.cs b/HandyControl/Controls/Input/TextBox.cs index e3224c98..aa7b32ab 100644 --- a/HandyControl/Controls/Input/TextBox.cs +++ b/HandyControl/Controls/Input/TextBox.cs @@ -32,7 +32,7 @@ namespace HandyControl.Controls /// 数据是否错误 /// public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register( - "IsError", typeof(bool), typeof(TextBox), new PropertyMetadata(default(bool))); + "IsError", typeof(bool), typeof(TextBox), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool IsError { @@ -68,7 +68,7 @@ namespace HandyControl.Controls /// 是否显示清除按钮 /// public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register( - "ShowClearButton", typeof(bool), typeof(TextBox), new PropertyMetadata(default(bool))); + "ShowClearButton", typeof(bool), typeof(TextBox), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool ShowClearButton { diff --git a/HandyControl/Controls/Loading/LoadingBase.cs b/HandyControl/Controls/Loading/LoadingBase.cs index f1afdb7d..20f38e07 100644 --- a/HandyControl/Controls/Loading/LoadingBase.cs +++ b/HandyControl/Controls/Loading/LoadingBase.cs @@ -4,6 +4,7 @@ using System.Windows.Data; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; +using HandyControl.Data; // ReSharper disable once CheckNamespace namespace HandyControl.Controls @@ -13,7 +14,7 @@ namespace HandyControl.Controls protected Storyboard Storyboard; public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register( - "IsRunning", typeof(bool), typeof(LoadingBase), new PropertyMetadata(true, (o, args) => + "IsRunning", typeof(bool), typeof(LoadingBase), new PropertyMetadata(BooleanBoxes.TrueBox, (o, args) => { var ctl = (LoadingBase) o; var v = (bool) args.NewValue; diff --git a/HandyControl/Controls/ScrollViewer.cs b/HandyControl/Controls/ScrollViewer.cs index 2d9650d9..779cc80e 100644 --- a/HandyControl/Controls/ScrollViewer.cs +++ b/HandyControl/Controls/ScrollViewer.cs @@ -4,6 +4,7 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; +using HandyControl.Data; using HandyControl.Tools; namespace HandyControl.Controls @@ -35,7 +36,7 @@ namespace HandyControl.Controls /// 是否响应鼠标滚轮操作 /// public static readonly DependencyProperty CanMouseWheelProperty = DependencyProperty.Register( - "CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(true)); + "CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(BooleanBoxes.TrueBox)); /// /// 是否响应鼠标滚轮操作 @@ -119,7 +120,7 @@ namespace HandyControl.Controls /// 是否支持惯性 /// public static readonly DependencyProperty IsEnableInertiaProperty = DependencyProperty.RegisterAttached( - "IsEnableInertia", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool))); + "IsEnableInertia", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(BooleanBoxes.FalseBox)); public static void SetIsEnableInertia(DependencyObject element, bool value) { @@ -144,7 +145,7 @@ namespace HandyControl.Controls /// 控件是否可以穿透点击 /// public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.RegisterAttached( - "IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool))); + "IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 控件是否可以穿透点击 diff --git a/HandyControl/Controls/TabControl/TabControl.cs b/HandyControl/Controls/TabControl/TabControl.cs index a04ad95d..39bf124e 100644 --- a/HandyControl/Controls/TabControl/TabControl.cs +++ b/HandyControl/Controls/TabControl/TabControl.cs @@ -3,6 +3,7 @@ using System.Collections.Specialized; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; +using HandyControl.Data; using HandyControl.Tools.Extension; // ReSharper disable once CheckNamespace @@ -29,7 +30,7 @@ namespace HandyControl.Controls /// 是否启用动画 /// public static readonly DependencyProperty IsEnableAnimationProperty = DependencyProperty.Register( - "IsEnableAnimation", typeof(bool), typeof(TabControl), new PropertyMetadata(default(bool))); + "IsEnableAnimation", typeof(bool), typeof(TabControl), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 是否启用动画 @@ -44,7 +45,7 @@ namespace HandyControl.Controls /// 是否可以拖动 /// public static readonly DependencyProperty IsDraggableProperty = DependencyProperty.Register( - "IsDraggable", typeof(bool), typeof(TabControl), new PropertyMetadata(default(bool))); + "IsDraggable", typeof(bool), typeof(TabControl), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 是否可以拖动 @@ -59,7 +60,7 @@ namespace HandyControl.Controls /// 是否显示关闭按钮 /// public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.Register( - "ShowCloseButton", typeof(bool), typeof(TabControl), new PropertyMetadata(default(bool))); + "ShowCloseButton", typeof(bool), typeof(TabControl), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 是否显示关闭按钮 @@ -74,7 +75,7 @@ namespace HandyControl.Controls /// 是否将标签填充 /// public static readonly DependencyProperty IsEnableTabFillProperty = DependencyProperty.Register( - "IsEnableTabFill", typeof(bool), typeof(TabControl), new PropertyMetadata(default(bool))); + "IsEnableTabFill", typeof(bool), typeof(TabControl), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 是否将标签填充 diff --git a/HandyControl/Controls/TabControl/TabPanel.cs b/HandyControl/Controls/TabControl/TabPanel.cs index 7cd3ad01..214353b1 100644 --- a/HandyControl/Controls/TabControl/TabPanel.cs +++ b/HandyControl/Controls/TabControl/TabPanel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; +using HandyControl.Data; using HandyControl.Tools; // ReSharper disable once CheckNamespace @@ -41,7 +42,7 @@ namespace HandyControl.Controls /// 是否将标签填充 /// public static readonly DependencyProperty IsEnableTabFillProperty = DependencyProperty.Register( - "IsEnableTabFill", typeof(bool), typeof(TabPanel), new PropertyMetadata(default(bool))); + "IsEnableTabFill", typeof(bool), typeof(TabPanel), new PropertyMetadata(BooleanBoxes.FalseBox)); /// /// 是否将标签填充 diff --git a/HandyControl/Controls/TimeBar/TimeBar.cs b/HandyControl/Controls/TimeBar/TimeBar.cs index ffce6df7..84dff82b 100644 --- a/HandyControl/Controls/TimeBar/TimeBar.cs +++ b/HandyControl/Controls/TimeBar/TimeBar.cs @@ -48,7 +48,7 @@ namespace HandyControl.Controls /// 是否显示刻度字符串 /// public static readonly DependencyProperty ShowSpeStrProperty = DependencyProperty.Register( - "ShowSpeStr", typeof(bool), typeof(TimeBar), new PropertyMetadata(default(bool))); + "ShowSpeStr", typeof(bool), typeof(TimeBar), new PropertyMetadata(BooleanBoxes.FalseBox)); public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register( "TimeFormat", typeof(string), typeof(TimeBar), new PropertyMetadata("yyyy-MM-dd HH:mm:ss")); diff --git a/HandyControl/Controls/Window/ImageBrowser.cs b/HandyControl/Controls/Window/ImageBrowser.cs index 08b5160b..c8e7e0cc 100644 --- a/HandyControl/Controls/Window/ImageBrowser.cs +++ b/HandyControl/Controls/Window/ImageBrowser.cs @@ -1,48 +1,26 @@ using System; -using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; using System.Windows.Media.Imaging; +using HandyControl.Data; using HandyControl.Interactivity; -using HandyControl.Tools; -using Microsoft.Win32; -// ReSharper disable once CheckNamespace namespace HandyControl.Controls { /// /// 图片浏览器 /// [TemplatePart(Name = ElementGridTop, Type = typeof(Grid))] - [TemplatePart(Name = ElementGridMain, Type = typeof(Grid))] - [TemplatePart(Name = ElementCanvasSmallImg, Type = typeof(Canvas))] - [TemplatePart(Name = ElementBorderMove, Type = typeof(Border))] - [TemplatePart(Name = ElementBorderBottom, Type = typeof(Border))] - [TemplatePart(Name = ElementImageMain, Type = typeof(Image))] + [TemplatePart(Name = ElementImageViewer, Type = typeof(ImageViewer))] public class ImageBrowser : WindowBorderless { #region Constants private const string ElementGridTop = "PART_GridTop"; - private const string ElementGridMain = "PART_GridMain"; - - private const string ElementCanvasSmallImg = "PART_CanvasSmallImg"; - - private const string ElementBorderMove = "PART_BorderMove"; - - private const string ElementBorderBottom = "PART_BorderBottom"; - - private const string ElementImageMain = "PART_ImageMain"; - - /// - /// 缩放比间隔 - /// - private const double ScaleInternal = 0.2; + private const string ElementImageViewer = "PART_ImageViewer"; #endregion Constants @@ -50,199 +28,18 @@ namespace HandyControl.Controls private Grid _gridTop; - private Grid _gridMain; - - private Canvas _canvasSmallImg; - - private Border _borderMove; - - private Border _borderBottom; - - private Image _imageMain; + private ImageViewer _imageViewer; #endregion Data static ImageBrowser() { - IsFullScreenProperty.AddOwner(typeof(ImageBrowser), new PropertyMetadata(default(bool))); - } - - internal static readonly DependencyProperty ImageContentProperty = DependencyProperty.Register( - "ImageContent", typeof(object), typeof(ImageBrowser), new PropertyMetadata(default(object))); - - internal object ImageContent - { - get => GetValue(ImageContentProperty); - set => SetValue(ImageContentProperty, value); - } - - internal static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register( - "ImageSource", typeof(BitmapFrame), typeof(ImageBrowser), new PropertyMetadata(default(BitmapFrame))); - - internal static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register( - "ImageMargin", typeof(Thickness), typeof(ImageBrowser), new PropertyMetadata(default(Thickness))); - - internal static readonly DependencyProperty ImageWidthProperty = DependencyProperty.Register( - "ImageWidth", typeof(double), typeof(ImageBrowser), new PropertyMetadata(default(double))); - - internal static readonly DependencyProperty ImageHeightProperty = DependencyProperty.Register( - "ImageHeight", typeof(double), typeof(ImageBrowser), new PropertyMetadata(default(double))); - - public static readonly DependencyProperty ImageScaleProperty = DependencyProperty.Register( - "ImageScale", typeof(double), typeof(ImageBrowser), new PropertyMetadata(1.0, OnImageScaleChanged)); - - internal static readonly DependencyProperty ScaleStrProperty = DependencyProperty.Register( - "ScaleStr", typeof(string), typeof(ImageBrowser), new PropertyMetadata("100%")); - - internal static readonly DependencyProperty ImageRotateProperty = DependencyProperty.Register( - "ImageRotate", typeof(double), typeof(ImageBrowser), new PropertyMetadata(default(double))); - - internal static readonly DependencyProperty ShowSmallImgProperty = DependencyProperty.Register( - "ShowSmallImg", typeof(bool), typeof(ImageBrowser), new PropertyMetadata(false)); - - /// - /// 图片保存对话框 - /// - private static readonly SaveFileDialog SaveFileDialog = new SaveFileDialog - { - Filter = $"{Properties.Langs.Lang.PngImg}|*.png" - }; - - public static readonly DependencyProperty ImgPathProperty = DependencyProperty.Register( - "ImgPath", typeof(string), typeof(ImageBrowser), new PropertyMetadata(default(string))); - - public string ImgPath - { - get => (string)GetValue(ImgPathProperty); - set => SetValue(ImgPathProperty, value); - } - - public static readonly DependencyProperty ImgSizeProperty = DependencyProperty.Register( - "ImgSize", typeof(long), typeof(ImageBrowser), new PropertyMetadata(-1L)); - - public long ImgSize - { - get => (long)GetValue(ImgSizeProperty); - set => SetValue(ImgSizeProperty, value); - } - - /// - /// 右下角小图片是否加载过 - /// - private bool _borderSmallIsLoaded; - - /// - /// 图片实际位置 - /// - private Thickness _imgActualMargin; - - /// - /// 图片实际旋转角度 - /// - private double _imgActualRotate; - - /// - /// 图片实际旋缩放比 - /// - private double _imgActualScale = 1; - - /// - /// 在图片上鼠标移动时的即时位置 - /// - private Point _imgCurrentPoint; - - /// - /// 在小图片上鼠标移动时的即时位置 - /// - private Point _imgSmallCurrentPoint; - - /// - /// 鼠标是否在图片上按下左键 - /// - private bool _imgIsMouseLeftButtonDown; - - /// - /// 鼠标是否在小图片上按下左键 - /// - private bool _imgSmallIsMouseLeftButtonDown; - - /// - /// 在图片上按下时图片的位置 - /// - private Thickness _imgMouseDownMargin; - - /// - /// 在小图片上按下时图片的位置 - /// - private Thickness _imgSmallMouseDownMargin; - - /// - /// 在图片上按下时鼠标的位置 - /// - private Point _imgMouseDownPoint; - - /// - /// 在小图片上按下时鼠标的位置 - /// - private Point _imgSmallMouseDownPoint; - - /// - /// 图片长宽比 - /// - private double _imgWidHeiScale; - - /// - /// 是否已经初始化 - /// - private bool _isLoaded; - - /// - /// 缩放高度间隔 - /// - private double _scaleInternalHeight; - - /// - /// 缩放宽度间隔 - /// - private double _scaleInternalWidth; - - /// - /// 底部BorderBottom(包含一些图片操作)是否显示中 - /// - private bool _showBorderBottom; - - /// - /// 关闭按钮是否显示中 - /// - private bool _showCloseButton; - - /// - /// 图片是否可以在x轴方向移动 - /// - private bool _canMoveX; - - /// - /// 图片是否可以在y轴方向移动 - /// - private bool _canMoveY; - - /// - /// 图片是否倾斜 - /// - private bool _isOblique; + IsFullScreenProperty.AddOwner(typeof(ImageBrowser), new PropertyMetadata(BooleanBoxes.FalseBox)); + } public ImageBrowser() { - Loaded += ImageBrowser_OnLoaded; - CommandBindings.Add(new CommandBinding(ControlCommands.Close, ButtonClose_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.Save, ButtonSave_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.Open, ButtonWindowsOpen_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.Restore, ButtonActual_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.Reduce, ButtonReduce_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.Enlarge, ButtonEnlarge_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.RotateLeft, ButtonRotateLeft_OnClick)); - CommandBindings.Add(new CommandBinding(ControlCommands.RotateRight, ButtonRotateRight_OnClick)); WindowStartupLocation = WindowStartupLocation.CenterScreen; WindowStyle = WindowStyle.None; @@ -255,20 +52,23 @@ namespace HandyControl.Controls /// public ImageBrowser(Uri uri) : this() { - try + Loaded += (s, e) => { - ImageSource = BitmapFrame.Create(uri); - ImgPath = uri.AbsolutePath; - if (File.Exists(ImgPath)) + try { - var info = new FileInfo(ImgPath); - ImgSize = info.Length; + _imageViewer.ImageSource = BitmapFrame.Create(uri); + _imageViewer.ImgPath = uri.AbsolutePath; + if (File.Exists(_imageViewer.ImgPath)) + { + var info = new FileInfo(_imageViewer.ImgPath); + _imageViewer.ImgSize = info.Length; + } } - } - catch - { - PopupWindow.ShowDialog(Properties.Langs.Lang.ErrorImgPath); - } + catch + { + PopupWindow.ShowDialog(Properties.Langs.Lang.ErrorImgPath); + } + }; } /// @@ -282,264 +82,29 @@ namespace HandyControl.Controls public override void OnApplyTemplate() { - if (_imageMain != null) - { - _imageMain.MouseLeftButtonDown -= ImageMain_OnMouseLeftButtonDown; - } - if (_gridTop != null) { _gridTop.MouseLeftButtonDown -= GridTop_OnMouseLeftButtonDown; } - if (_gridMain != null) + if (_imageViewer != null) { - _gridMain.MouseLeftButtonDown -= GridMain_OnMouseLeftButtonDown; - } - - if (_canvasSmallImg != null) - { - _canvasSmallImg.MouseLeftButtonDown -= CanvasSmallImg_OnMouseLeftButtonDown; - _canvasSmallImg.MouseLeftButtonUp -= CanvasSmallImg_OnMouseLeftButtonUp; - _canvasSmallImg.MouseMove -= CanvasSmallImg_OnMouseMove; - _canvasSmallImg.MouseLeave -= CanvasSmallImg_OnMouseLeave; + _imageViewer.MouseLeftButtonDown -= ImageViewer_MouseLeftButtonDown; } base.OnApplyTemplate(); _gridTop = GetTemplateChild(ElementGridTop) as Grid; - _gridMain = GetTemplateChild(ElementGridMain) as Grid; - _canvasSmallImg = GetTemplateChild(ElementCanvasSmallImg) as Canvas; - _borderMove = GetTemplateChild(ElementBorderMove) as Border; - _imageMain = GetTemplateChild(ElementImageMain) as Image; - _borderBottom = GetTemplateChild(ElementBorderBottom) as Border; - - if (_imageMain != null) - { - _imageMain.MouseLeftButtonDown += ImageMain_OnMouseLeftButtonDown; - } + _imageViewer = GetTemplateChild(ElementImageViewer) as ImageViewer; if (_gridTop != null) { _gridTop.MouseLeftButtonDown += GridTop_OnMouseLeftButtonDown; } - if (_gridMain != null) + if (_imageViewer != null) { - _gridMain.MouseLeftButtonDown += GridMain_OnMouseLeftButtonDown; - } - - if (_canvasSmallImg != null) - { - _canvasSmallImg.MouseLeftButtonDown += CanvasSmallImg_OnMouseLeftButtonDown; - _canvasSmallImg.MouseLeftButtonUp += CanvasSmallImg_OnMouseLeftButtonUp; - _canvasSmallImg.MouseMove += CanvasSmallImg_OnMouseMove; - _canvasSmallImg.MouseLeave += CanvasSmallImg_OnMouseLeave; - } - } - - internal BitmapFrame ImageSource - { - get => (BitmapFrame)GetValue(ImageSourceProperty); - set => SetValue(ImageSourceProperty, value); - } - - internal Thickness ImageMargin - { - get => (Thickness)GetValue(ImageMarginProperty); - set => SetValue(ImageMarginProperty, value); - } - - internal double ImageWidth - { - get => (double)GetValue(ImageWidthProperty); - set => SetValue(ImageWidthProperty, value); - } - - internal double ImageHeight - { - get => (double)GetValue(ImageHeightProperty); - set => SetValue(ImageHeightProperty, value); - } - - public double ImageScale - { - get => (double)GetValue(ImageScaleProperty); - set => SetValue(ImageScaleProperty, value); - } - - internal string ScaleStr - { - get => (string)GetValue(ScaleStrProperty); - set => SetValue(ScaleStrProperty, value); - } - - internal double ImageRotate - { - get => (double)GetValue(ImageRotateProperty); - set => SetValue(ImageRotateProperty, value); - } - - internal bool ShowSmallImg - { - get => (bool)GetValue(ShowSmallImgProperty); - set => SetValue(ShowSmallImgProperty, value); - } - - /// - /// 图片原始宽度 - /// - private double ImageOriWidth { get; set; } - - /// - /// 图片原始高度 - /// - private double ImageOriHeight { get; set; } - - /// - /// 关闭按钮是否显示中 - /// - public bool ShowCloseButton - { - get => _showCloseButton; - set - { - if (_showCloseButton == value) return; - _gridTop.BeginAnimation(OpacityProperty, - value ? AnimationHelper.CreateAnimation(1, 100) : AnimationHelper.CreateAnimation(0, 400)); - _showCloseButton = value; - } - } - - /// - /// 底部BorderBottom(包含一些图片操作)是否显示中 - /// - public bool ShowBorderBottom - { - get => _showBorderBottom; - set - { - if (_showBorderBottom == value) return; - _borderBottom?.BeginAnimation(OpacityProperty, - value ? AnimationHelper.CreateAnimation(1, 100) : AnimationHelper.CreateAnimation(0, 400)); - _showBorderBottom = value; - } - } - - private static void OnImageScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (d is ImageBrowser imageBrowser && e.NewValue is double newValue) - { - imageBrowser.ImageWidth = imageBrowser.ImageOriWidth * newValue; - imageBrowser.ImageHeight = imageBrowser.ImageOriHeight * newValue; - imageBrowser.ScaleStr = $"{newValue * 100:#0}%"; - } - } - - /// - /// 初始化 - /// - private void Init() - { - if (ImageSource == null) return; - - double width; - double height; - - if (!_isOblique) - { - width = ImageSource.Width; - height = ImageSource.Height; - } - else - { - width = ImageSource.Height; - height = ImageSource.Width; - } - - ImageWidth = width; - ImageHeight = height; - ImageOriWidth = width; - ImageOriHeight = height; - _scaleInternalWidth = ImageOriWidth * ScaleInternal; - _scaleInternalHeight = ImageOriHeight * ScaleInternal; - - if (Math.Abs(height - 0) < 0.001 || Math.Abs(width - 0) < 0.001) - { - PopupWindow.ShowDialog(Properties.Langs.Lang.ErrorImgSize); - return; - } - _imgWidHeiScale = width / height; - var scaleWindow = ActualWidth / ActualHeight; - if (_imgWidHeiScale > scaleWindow) - { - if (width > ActualWidth) - ImageScale = ActualWidth / width; - } - else if (height > ActualHeight) - { - ImageScale = ActualHeight / height; - } - ImageMargin = new Thickness((ActualWidth - ImageWidth) / 2, (ActualHeight - ImageHeight) / 2, 0, 0); - - _imgActualScale = 1; - _imgActualMargin = ImageMargin; - } - - private void ButtonActual_OnClick(object sender, RoutedEventArgs e) - { - var scaleAnimation = AnimationHelper.CreateAnimation(1); - scaleAnimation.FillBehavior = FillBehavior.Stop; - _imgActualScale = 1; - scaleAnimation.Completed += (s, e1) => - { - ImageScale = 1; - _canMoveX = ImageWidth > ActualWidth; - _canMoveY = ImageHeight > ActualHeight; - BorderSmallShowSwitch(); - }; - var thickness = new Thickness((ActualWidth - ImageOriWidth) / 2, (ActualHeight - ImageOriHeight) / 2, 0, 0); - var marginAnimation = AnimationHelper.CreateAnimation(thickness); - marginAnimation.FillBehavior = FillBehavior.Stop; - _imgActualMargin = thickness; - marginAnimation.Completed += (s, e1) => { ImageMargin = thickness; }; - - BeginAnimation(ImageScaleProperty, scaleAnimation); - BeginAnimation(ImageMarginProperty, marginAnimation); - } - - private void ButtonReduce_OnClick(object sender, RoutedEventArgs e) => ScaleImg(false); - - private void ButtonEnlarge_OnClick(object sender, RoutedEventArgs e) => ScaleImg(true); - - private void ButtonRotateLeft_OnClick(object sender, RoutedEventArgs e) => RotateImg(_imgActualRotate - 90); - - private void ButtonRotateRight_OnClick(object sender, RoutedEventArgs e) => RotateImg(_imgActualRotate + 90); - - private void ButtonSave_OnClick(object sender, RoutedEventArgs e) - { - SaveFileDialog.FileName = $"{DateTime.Now:yyyy-M-d-h-m-s.fff}"; - if (SaveFileDialog.ShowDialog() == true) - { - var path = SaveFileDialog.FileName; - using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) - { - var encoder = new PngBitmapEncoder(); - encoder.Frames.Add(BitmapFrame.Create(ImageSource)); - encoder.Save(fileStream); - } - } - } - - private void ButtonWindowsOpen_OnClick(object sender, RoutedEventArgs e) - { - try - { - Process.Start(ImgPath); - } - catch (Exception exception) - { - PopupWindow.ShowDialog(exception.Message); + _imageViewer.MouseLeftButtonDown += ImageViewer_MouseLeftButtonDown; } } @@ -553,385 +118,12 @@ namespace HandyControl.Controls } } - private void GridMain_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + private void ImageViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { - if (e.LeftButton == MouseButtonState.Pressed && !(ImageWidth > ActualWidth || ImageHeight > ActualHeight)) + if (e.LeftButton == MouseButtonState.Pressed && !(_imageViewer.ImageWidth > ActualWidth || _imageViewer.ImageHeight > ActualHeight)) { DragMove(); } } - - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - MoveImg(); - } - - protected override void OnMouseLeave(MouseEventArgs e) - { - base.OnMouseLeave(e); - _imgIsMouseLeftButtonDown = false; - } - - protected override void OnMouseWheel(MouseWheelEventArgs e) - { - base.OnMouseWheel(e); - ScaleImg(e.Delta > 0); - } - - protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) - { - base.OnRenderSizeChanged(sizeInfo); - - if (!_isLoaded) return; - - if (ImageWidth < 0.001 || ImageHeight < 0.001) return; - - _canMoveX = true; - _canMoveY = true; - - var marginX = ImageMargin.Left; - var marginY = ImageMargin.Top; - - if (ImageWidth <= ActualWidth) - { - _canMoveX = false; - marginX = (ActualWidth - ImageWidth) / 2; - } - - if (ImageHeight <= ActualHeight) - { - _canMoveY = false; - marginY = (ActualHeight - ImageHeight) / 2; - } - - ImageMargin = new Thickness(marginX, marginY, 0, 0); - _imgActualMargin = ImageMargin; - - BorderSmallShowSwitch(); - _imgSmallMouseDownPoint = Mouse.GetPosition(_canvasSmallImg); - _imgSmallMouseDownMargin = _borderMove.Margin; - MoveSmallImg(_imgSmallMouseDownMargin.Left, _imgSmallMouseDownMargin.Top); - } - - protected override void OnMouseDoubleClick(MouseButtonEventArgs e) - { - base.OnMouseDoubleClick(e); - - if (e.GetPosition(_gridTop).Y > _gridTop.ActualHeight) return; - IsFullScreen = !IsFullScreen; - } - - private void ImageBrowser_OnLoaded(object sender, RoutedEventArgs e) - { - if (_isLoaded) return; - Init(); - _isLoaded = true; - } - - private void ImageMain_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - if (e.LeftButton == MouseButtonState.Pressed && !(ImageWidth > ActualWidth || ImageHeight > ActualHeight)) - { - DragMove(); - return; - } - _imgMouseDownPoint = Mouse.GetPosition(_gridMain); - _imgMouseDownMargin = ImageMargin; - _imgIsMouseLeftButtonDown = true; - } - - protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnPreviewMouseLeftButtonUp(e); - _imgIsMouseLeftButtonDown = false; - } - - /// - /// 右下角小图片显示切换 - /// - private void BorderSmallShowSwitch() - { - if (_canMoveX || _canMoveY) - { - if (!_borderSmallIsLoaded) - { - _canvasSmallImg.Background = new VisualBrush(_imageMain); - InitBorderSmall(); - _borderSmallIsLoaded = true; - } - ShowSmallImg = true; - UpdateBorderSmall(); - } - else - { - ShowSmallImg = false; - } - } - - /// - /// 初始化右下角小图片 - /// - private void InitBorderSmall() - { - var scaleWindow = _canvasSmallImg.MaxWidth / _canvasSmallImg.MaxHeight; - if (_imgWidHeiScale > scaleWindow) - { - _canvasSmallImg.Width = _canvasSmallImg.MaxWidth; - _canvasSmallImg.Height = _canvasSmallImg.Width / _imgWidHeiScale; - } - else - { - _canvasSmallImg.Width = _canvasSmallImg.MaxHeight * _imgWidHeiScale; - _canvasSmallImg.Height = _canvasSmallImg.MaxHeight; - } - } - - /// - /// 更新右下角小图片 - /// - private void UpdateBorderSmall() - { - if (!ShowSmallImg) return; - - var widthMin = Math.Min(ImageWidth, ActualWidth); - var heightMin = Math.Min(ImageHeight, ActualHeight); - - _borderMove.Width = widthMin / ImageWidth * _canvasSmallImg.Width; - _borderMove.Height = heightMin / ImageHeight * _canvasSmallImg.Height; - - var marginX = -ImageMargin.Left / ImageWidth * _canvasSmallImg.Width; - var marginY = -ImageMargin.Top / ImageHeight * _canvasSmallImg.Height; - - var marginXMax = _canvasSmallImg.Width - _borderMove.Width; - var marginYMax = _canvasSmallImg.Height - _borderMove.Height; - - marginX = Math.Max(0, marginX); - marginX = Math.Min(marginXMax, marginX); - marginY = Math.Max(0, marginY); - marginY = Math.Min(marginYMax, marginY); - - _borderMove.Margin = new Thickness(marginX, marginY, 0, 0); - } - - /// - /// 缩放图片 - /// - /// - private void ScaleImg(bool isEnlarge) - { - if (Mouse.LeftButton == MouseButtonState.Pressed) return; - var oldImageWidth = ImageWidth; - var olgImageHeight = ImageHeight; - - var tempScale = isEnlarge ? _imgActualScale + ScaleInternal : _imgActualScale - ScaleInternal; - if (Math.Abs(tempScale) < ScaleInternal || Math.Abs(tempScale - 50) < 0.001) - return; - - ImageScale = tempScale; - - var posCanvas = Mouse.GetPosition(_gridMain); - var posImg = new Point(posCanvas.X - _imgActualMargin.Left, posCanvas.Y - _imgActualMargin.Top); - - var marginX = .5 * _scaleInternalWidth; - var marginY = .5 * _scaleInternalHeight; - - if (ImageWidth > ActualWidth) - { - _canMoveX = true; - if (ImageHeight > ActualHeight) - { - _canMoveY = true; - marginX = posImg.X / oldImageWidth * _scaleInternalWidth; - marginY = posImg.Y / olgImageHeight * _scaleInternalHeight; - } - else - { - _canMoveY = false; - } - } - else - { - _canMoveY = ImageHeight > ActualHeight; - _canMoveX = false; - } - - Thickness thickness; - if (isEnlarge) - { - thickness = new Thickness(_imgActualMargin.Left - marginX, _imgActualMargin.Top - marginY, 0, 0); - } - else - { - var marginActualX = _imgActualMargin.Left + marginX; - var marginActualY = _imgActualMargin.Top + marginY; - var subX = ImageWidth - ActualWidth; - var subY = ImageHeight - ActualHeight; - - var right = Math.Abs(_borderMove.Width - _canvasSmallImg.ActualWidth + _borderMove.Margin.Left); - var top = Math.Abs(_borderMove.Height - _canvasSmallImg.ActualHeight + _borderMove.Margin.Top); - if (Math.Abs(ImageMargin.Left) < 0.001 || right < 0.001) - { - marginActualX = _imgActualMargin.Left + _borderMove.Margin.Left / (_canvasSmallImg.ActualWidth - _borderMove.Width) * _scaleInternalWidth; - } - if (Math.Abs(ImageMargin.Top) < 0.001 || top < 0.001) - { - marginActualY = _imgActualMargin.Top + _borderMove.Margin.Top / (_canvasSmallImg.ActualHeight - _borderMove.Height) * _scaleInternalHeight; - } - if (subX < 0.001) - { - marginActualX = (ActualWidth - ImageWidth) / 2; - } - if (subY < 0.001) - { - marginActualY = (ActualHeight - ImageHeight) / 2; - } - thickness = new Thickness(marginActualX, marginActualY, 0, 0); - } - - ImageMargin = thickness; - _imgActualScale = tempScale; - _imgActualMargin = thickness; - BorderSmallShowSwitch(); - } - - /// - /// 旋转图片 - /// - /// - private void RotateImg(double rotate) - { - _imgActualRotate = rotate; - - _isOblique = ((int)_imgActualRotate - 90) % 180 == 0; - ShowSmallImg = false; - Init(); - InitBorderSmall(); - - var animation = AnimationHelper.CreateAnimation(rotate); - animation.Completed += (s, e1) => { ImageRotate = rotate; }; - animation.FillBehavior = FillBehavior.Stop; - BeginAnimation(ImageRotateProperty, animation); - } - - /// - /// 移动图片 - /// - private void MoveImg() - { - _imgCurrentPoint = Mouse.GetPosition(_gridMain); - ShowCloseButton = _imgCurrentPoint.Y < 200; - ShowBorderBottom = _imgCurrentPoint.Y > ActualHeight - 200; - - if (_imgIsMouseLeftButtonDown) - { - var subX = _imgCurrentPoint.X - _imgMouseDownPoint.X; - var subY = _imgCurrentPoint.Y - _imgMouseDownPoint.Y; - - var marginX = _imgMouseDownMargin.Left; - if (ImageWidth > ActualWidth) - { - marginX = _imgMouseDownMargin.Left + subX; - if (marginX >= 0) - { - marginX = 0; - } - else if (-marginX + ActualWidth >= ImageWidth) - { - marginX = ActualWidth - ImageWidth; - } - _canMoveX = true; - } - - var marginY = _imgMouseDownMargin.Top; - if (ImageHeight > ActualHeight) - { - marginY = _imgMouseDownMargin.Top + subY; - if (marginY >= 0) - { - marginY = 0; - } - else if (-marginY + ActualHeight >= ImageHeight) - { - marginY = ActualHeight - ImageHeight; - } - _canMoveY = true; - } - - ImageMargin = new Thickness(marginX, marginY, 0, 0); - _imgActualMargin = ImageMargin; - - UpdateBorderSmall(); - } - } - - /// - /// 移动小图片 - /// - private void MoveSmallImg() - { - if (_imgSmallIsMouseLeftButtonDown) - { - _imgSmallCurrentPoint = Mouse.GetPosition(_canvasSmallImg); - - var subX = _imgSmallCurrentPoint.X - _imgSmallMouseDownPoint.X; - var subY = _imgSmallCurrentPoint.Y - _imgSmallMouseDownPoint.Y; - - var marginX = _imgSmallMouseDownMargin.Left + subX; - var marginY = _imgSmallMouseDownMargin.Top + subY; - - MoveSmallImg(marginX, marginY); - } - } - - private void MoveSmallImg(double marginX, double marginY) - { - if (marginX < 0) - { - marginX = 0; - } - else if (marginX + _borderMove.Width >= _canvasSmallImg.ActualWidth) - { - marginX = _canvasSmallImg.ActualWidth - _borderMove.Width; - } - if (marginY < 0) - { - marginY = 0; - } - else if (marginY + _borderMove.Height >= _canvasSmallImg.ActualHeight) - { - marginY = _canvasSmallImg.ActualHeight - _borderMove.Height; - } - _borderMove.Margin = new Thickness(marginX, marginY, 0, 0); - - var marginActualX = (ActualWidth - ImageWidth) / 2; - var marginActualY = (ActualHeight - ImageHeight) / 2; - - if (_canMoveX) - { - marginActualX = -marginX / _canvasSmallImg.ActualWidth * ImageWidth; - } - if (_canMoveY) - { - marginActualY = -marginY / _canvasSmallImg.ActualHeight * ImageHeight; - } - - ImageMargin = new Thickness(marginActualX, marginActualY, 0, 0); - _imgActualMargin = ImageMargin; - } - - private void CanvasSmallImg_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - _imgSmallMouseDownPoint = Mouse.GetPosition(_canvasSmallImg); - _imgSmallMouseDownMargin = _borderMove.Margin; - _imgSmallIsMouseLeftButtonDown = true; - e.Handled = true; - } - - private void CanvasSmallImg_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) => _imgSmallIsMouseLeftButtonDown = false; - - private void CanvasSmallImg_OnMouseMove(object sender, MouseEventArgs e) => MoveSmallImg(); - - private void CanvasSmallImg_OnMouseLeave(object sender, MouseEventArgs e) => _imgSmallIsMouseLeftButtonDown = false; } } \ No newline at end of file diff --git a/HandyControl/Controls/Window/PopupWindow.cs b/HandyControl/Controls/Window/PopupWindow.cs index 93167dd5..aa497740 100644 --- a/HandyControl/Controls/Window/PopupWindow.cs +++ b/HandyControl/Controls/Window/PopupWindow.cs @@ -105,7 +105,7 @@ namespace HandyControl.Controls public FrameworkElement PopupElement { get; set; } public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register( - "ShowTitle", typeof(bool), typeof(PopupWindow), new PropertyMetadata(true)); + "ShowTitle", typeof(bool), typeof(PopupWindow), new PropertyMetadata(BooleanBoxes.TrueBox)); public bool ShowTitle { @@ -114,7 +114,7 @@ namespace HandyControl.Controls } public static readonly DependencyProperty ShowCancelProperty = DependencyProperty.Register( - "ShowCancel", typeof(bool), typeof(PopupWindow), new PropertyMetadata(default(bool))); + "ShowCancel", typeof(bool), typeof(PopupWindow), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool ShowCancel { @@ -123,7 +123,7 @@ namespace HandyControl.Controls } public static readonly DependencyProperty ShowBorderProperty = DependencyProperty.Register( - "ShowBorder", typeof(bool), typeof(PopupWindow), new PropertyMetadata(default(bool))); + "ShowBorder", typeof(bool), typeof(PopupWindow), new PropertyMetadata(BooleanBoxes.FalseBox)); public bool ShowBorder { @@ -187,9 +187,9 @@ namespace HandyControl.Controls AllowsTransparency = true, WindowStyle = WindowStyle.None, ContentStr = message, - WindowStartupLocation = WindowStartupLocation.CenterScreen + WindowStartupLocation = WindowStartupLocation.CenterScreen, + Background = ResourceHelper.GetResource(ResourceToken.PrimaryBrush) }; - window.Background = ResourceHelper.GetResource(ResourceToken.PrimaryBrush); window.Show(); } diff --git a/HandyControl/Controls/Window/WindowBorderless.cs b/HandyControl/Controls/Window/WindowBorderless.cs index 1873cb96..94db0f95 100644 --- a/HandyControl/Controls/Window/WindowBorderless.cs +++ b/HandyControl/Controls/Window/WindowBorderless.cs @@ -60,13 +60,13 @@ namespace HandyControl.Controls new PropertyMetadata(28.0)); public static readonly DependencyProperty ShowNonClientAreaProperty = DependencyProperty.Register( - "ShowNonClientArea", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(true)); + "ShowNonClientArea", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(BooleanBoxes.TrueBox)); public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register( - "ShowTitle", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(default(bool))); + "ShowTitle", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(BooleanBoxes.FalseBox)); public static readonly DependencyProperty IsFullScreenProperty = DependencyProperty.Register( - "IsFullScreen", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(default(bool), + "IsFullScreen", typeof(bool), typeof(WindowBorderless), new PropertyMetadata(BooleanBoxes.FalseBox, (o, args) => { var ctl = (WindowBorderless)o; diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj index 07572ee5..551cfac4 100644 --- a/HandyControl/HandyControl.csproj +++ b/HandyControl/HandyControl.csproj @@ -51,6 +51,7 @@ + @@ -400,6 +401,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/HandyControl/Interactivity/FluidMoveBehavior.cs b/HandyControl/Interactivity/FluidMoveBehavior.cs index e980e3a8..be3190e4 100644 --- a/HandyControl/Interactivity/FluidMoveBehavior.cs +++ b/HandyControl/Interactivity/FluidMoveBehavior.cs @@ -7,6 +7,7 @@ using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; +using HandyControl.Data; namespace HandyControl.Interactivity { @@ -28,7 +29,7 @@ namespace HandyControl.Interactivity public static readonly DependencyProperty FloatAboveProperty = DependencyProperty.Register("FloatAbove", typeof(bool), typeof(FluidMoveBehavior), - new PropertyMetadata(true)); + new PropertyMetadata(BooleanBoxes.TrueBox)); private static readonly DependencyProperty HasTransformWrapperProperty = DependencyProperty.RegisterAttached("HasTransformWrapper", typeof(bool), diff --git a/HandyControl/Interactivity/FluidMoveBehaviorBase.cs b/HandyControl/Interactivity/FluidMoveBehaviorBase.cs index 723194f8..01d0373b 100644 --- a/HandyControl/Interactivity/FluidMoveBehaviorBase.cs +++ b/HandyControl/Interactivity/FluidMoveBehaviorBase.cs @@ -5,6 +5,7 @@ using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Media; +using HandyControl.Data; namespace HandyControl.Interactivity { @@ -18,7 +19,7 @@ namespace HandyControl.Interactivity new PropertyMetadata(null)); public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register("IsActive", - typeof(bool), typeof(FluidMoveBehaviorBase), new PropertyMetadata(true)); + typeof(bool), typeof(FluidMoveBehaviorBase), new PropertyMetadata(BooleanBoxes.TrueBox)); private static DateTime LastPurgeTick = DateTime.MinValue; diff --git a/HandyControl/Themes/Styles/ImageViewer.xaml b/HandyControl/Themes/Styles/ImageViewer.xaml new file mode 100644 index 00000000..016ce182 --- /dev/null +++ b/HandyControl/Themes/Styles/ImageViewer.xaml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HandyControl/Themes/Styles/Style.xaml b/HandyControl/Themes/Styles/Style.xaml index a48ec931..4b1ae3c8 100644 --- a/HandyControl/Themes/Styles/Style.xaml +++ b/HandyControl/Themes/Styles/Style.xaml @@ -37,6 +37,7 @@ + \ No newline at end of file diff --git a/HandyControl/Themes/Styles/Window.xaml b/HandyControl/Themes/Styles/Window.xaml index 0cd3d5d7..6b3b80b7 100644 --- a/HandyControl/Themes/Styles/Window.xaml +++ b/HandyControl/Themes/Styles/Window.xaml @@ -195,63 +195,42 @@ + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + - - + +