add imageviewer
This commit is contained in:
1 parent
df00d8b69a
commit
76f7b5a247
25 files changed
+1055
-917
No files matched your search
@@ -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);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows;
|
||||
using HandyControl.Data;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace HandyControl.Controls
|
||||
@@ -19,7 +20,7 @@ namespace HandyControl.Controls
|
||||
/// 是否隐藏元素
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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";
|
||||
|
||||
/// <summary>
|
||||
/// 缩放比间隔
|
||||
/// </summary>
|
||||
private const double ScaleInternal = 0.2;
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region Data
|
||||
|
||||
/// <summary>
|
||||
/// 图片保存对话框
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// 右下角小图片是否加载过
|
||||
/// </summary>
|
||||
private bool _borderSmallIsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否可以在x轴方向移动
|
||||
/// </summary>
|
||||
private bool _canMoveX;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否可以在y轴方向移动
|
||||
/// </summary>
|
||||
private bool _canMoveY;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际位置
|
||||
/// </summary>
|
||||
private Thickness _imgActualMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际旋转角度
|
||||
/// </summary>
|
||||
private double _imgActualRotate;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际旋缩放比
|
||||
/// </summary>
|
||||
private double _imgActualScale = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上鼠标移动时的即时位置
|
||||
/// </summary>
|
||||
private Point _imgCurrentPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标是否在图片上按下左键
|
||||
/// </summary>
|
||||
private bool _imgIsMouseLeftButtonDown;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上按下时图片的位置
|
||||
/// </summary>
|
||||
private Thickness _imgMouseDownMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上按下时鼠标的位置
|
||||
/// </summary>
|
||||
private Point _imgMouseDownPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上鼠标移动时的即时位置
|
||||
/// </summary>
|
||||
private Point _imgSmallCurrentPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标是否在小图片上按下左键
|
||||
/// </summary>
|
||||
private bool _imgSmallIsMouseLeftButtonDown;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上按下时图片的位置
|
||||
/// </summary>
|
||||
private Thickness _imgSmallMouseDownMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上按下时鼠标的位置
|
||||
/// </summary>
|
||||
private Point _imgSmallMouseDownPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 图片长宽比
|
||||
/// </summary>
|
||||
private double _imgWidHeiScale;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经初始化
|
||||
/// </summary>
|
||||
private bool _isLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否倾斜
|
||||
/// </summary>
|
||||
private bool _isOblique;
|
||||
|
||||
/// <summary>
|
||||
/// 缩放高度间隔
|
||||
/// </summary>
|
||||
private double _scaleInternalHeight;
|
||||
|
||||
/// <summary>
|
||||
/// 缩放宽度间隔
|
||||
/// </summary>
|
||||
private double _scaleInternalWidth;
|
||||
|
||||
/// <summary>
|
||||
/// 底部BorderBottom(包含一些图片操作)是否显示中
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带一个图片Uri的构造函数
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带一个图片路径的构造函数
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示全屏按钮
|
||||
/// </summary>
|
||||
internal static readonly DependencyProperty ShowFullScreenButtonProperty = DependencyProperty.Register(
|
||||
"ShowFullScreenButton", typeof(bool), typeof(ImageViewer), new PropertyMetadata(BooleanBoxes.FalseBox));
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮是否显示中
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示全屏按钮
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片原始宽度
|
||||
/// </summary>
|
||||
private double ImageOriWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片原始高度
|
||||
/// </summary>
|
||||
private double ImageOriHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮是否显示中
|
||||
/// </summary>
|
||||
internal bool ShowCloseButton
|
||||
{
|
||||
get => (bool)GetValue(ShowCloseButtonProperty);
|
||||
set => SetValue(ShowCloseButtonProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 底部BorderBottom(包含一些图片操作)是否显示中
|
||||
/// </summary>
|
||||
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}%";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 右下角小图片显示切换
|
||||
/// </summary>
|
||||
private void BorderSmallShowSwitch()
|
||||
{
|
||||
if (_canMoveX || _canMoveY)
|
||||
{
|
||||
if (!_borderSmallIsLoaded)
|
||||
{
|
||||
_canvasSmallImg.Background = new VisualBrush(_imageMain);
|
||||
InitBorderSmall();
|
||||
_borderSmallIsLoaded = true;
|
||||
}
|
||||
|
||||
ShowSmallImgInternal = true;
|
||||
UpdateBorderSmall();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowSmallImgInternal = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化右下角小图片
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新右下角小图片
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缩放图片
|
||||
/// </summary>
|
||||
/// <param name="isEnlarge"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 旋转图片
|
||||
/// </summary>
|
||||
/// <param name="rotate"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动图片
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动小图片
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -301,7 +301,7 @@ namespace HandyControl.Controls
|
||||
/// 是否显示上下调值按钮
|
||||
/// </summary>
|
||||
internal static readonly DependencyProperty ShowUpDownButtonProperty = DependencyProperty.Register(
|
||||
"ShowUpDownButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(true));
|
||||
"ShowUpDownButton", typeof(bool), typeof(NumericUpDown), new PropertyMetadata(BooleanBoxes.TrueBox));
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示上下调值按钮
|
||||
@@ -316,7 +316,7 @@ namespace HandyControl.Controls
|
||||
/// 数据是否错误
|
||||
/// </summary>
|
||||
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
|
||||
/// 是否显示清除按钮
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace HandyControl.Controls
|
||||
/// 数据是否错误
|
||||
/// </summary>
|
||||
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
|
||||
/// 是否显示清除按钮
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
/// 是否响应鼠标滚轮操作
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CanMouseWheelProperty = DependencyProperty.Register(
|
||||
"CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(true));
|
||||
"CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(BooleanBoxes.TrueBox));
|
||||
|
||||
/// <summary>
|
||||
/// 是否响应鼠标滚轮操作
|
||||
@@ -119,7 +120,7 @@ namespace HandyControl.Controls
|
||||
/// 是否支持惯性
|
||||
/// </summary>
|
||||
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
|
||||
/// 控件是否可以穿透点击
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 控件是否可以穿透点击
|
||||
|
||||
@@ -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
|
||||
/// 是否启用动画
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用动画
|
||||
@@ -44,7 +45,7 @@ namespace HandyControl.Controls
|
||||
/// 是否可以拖动
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以拖动
|
||||
@@ -59,7 +60,7 @@ namespace HandyControl.Controls
|
||||
/// 是否显示关闭按钮
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示关闭按钮
|
||||
@@ -74,7 +75,7 @@ namespace HandyControl.Controls
|
||||
/// 是否将标签填充
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否将标签填充
|
||||
|
||||
@@ -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
|
||||
/// 是否将标签填充
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 是否将标签填充
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace HandyControl.Controls
|
||||
/// 是否显示刻度字符串
|
||||
/// </summary>
|
||||
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"));
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片浏览器
|
||||
/// </summary>
|
||||
[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";
|
||||
|
||||
/// <summary>
|
||||
/// 缩放比间隔
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 图片保存对话框
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 右下角小图片是否加载过
|
||||
/// </summary>
|
||||
private bool _borderSmallIsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际位置
|
||||
/// </summary>
|
||||
private Thickness _imgActualMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际旋转角度
|
||||
/// </summary>
|
||||
private double _imgActualRotate;
|
||||
|
||||
/// <summary>
|
||||
/// 图片实际旋缩放比
|
||||
/// </summary>
|
||||
private double _imgActualScale = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上鼠标移动时的即时位置
|
||||
/// </summary>
|
||||
private Point _imgCurrentPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上鼠标移动时的即时位置
|
||||
/// </summary>
|
||||
private Point _imgSmallCurrentPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标是否在图片上按下左键
|
||||
/// </summary>
|
||||
private bool _imgIsMouseLeftButtonDown;
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标是否在小图片上按下左键
|
||||
/// </summary>
|
||||
private bool _imgSmallIsMouseLeftButtonDown;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上按下时图片的位置
|
||||
/// </summary>
|
||||
private Thickness _imgMouseDownMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上按下时图片的位置
|
||||
/// </summary>
|
||||
private Thickness _imgSmallMouseDownMargin;
|
||||
|
||||
/// <summary>
|
||||
/// 在图片上按下时鼠标的位置
|
||||
/// </summary>
|
||||
private Point _imgMouseDownPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 在小图片上按下时鼠标的位置
|
||||
/// </summary>
|
||||
private Point _imgSmallMouseDownPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 图片长宽比
|
||||
/// </summary>
|
||||
private double _imgWidHeiScale;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经初始化
|
||||
/// </summary>
|
||||
private bool _isLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// 缩放高度间隔
|
||||
/// </summary>
|
||||
private double _scaleInternalHeight;
|
||||
|
||||
/// <summary>
|
||||
/// 缩放宽度间隔
|
||||
/// </summary>
|
||||
private double _scaleInternalWidth;
|
||||
|
||||
/// <summary>
|
||||
/// 底部BorderBottom(包含一些图片操作)是否显示中
|
||||
/// </summary>
|
||||
private bool _showBorderBottom;
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮是否显示中
|
||||
/// </summary>
|
||||
private bool _showCloseButton;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否可以在x轴方向移动
|
||||
/// </summary>
|
||||
private bool _canMoveX;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否可以在y轴方向移动
|
||||
/// </summary>
|
||||
private bool _canMoveY;
|
||||
|
||||
/// <summary>
|
||||
/// 图片是否倾斜
|
||||
/// </summary>
|
||||
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
|
||||
/// <param name="uri"></param>
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片原始宽度
|
||||
/// </summary>
|
||||
private double ImageOriWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片原始高度
|
||||
/// </summary>
|
||||
private double ImageOriHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮是否显示中
|
||||
/// </summary>
|
||||
public bool ShowCloseButton
|
||||
{
|
||||
get => _showCloseButton;
|
||||
set
|
||||
{
|
||||
if (_showCloseButton == value) return;
|
||||
_gridTop.BeginAnimation(OpacityProperty,
|
||||
value ? AnimationHelper.CreateAnimation(1, 100) : AnimationHelper.CreateAnimation(0, 400));
|
||||
_showCloseButton = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 底部BorderBottom(包含一些图片操作)是否显示中
|
||||
/// </summary>
|
||||
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}%";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 右下角小图片显示切换
|
||||
/// </summary>
|
||||
private void BorderSmallShowSwitch()
|
||||
{
|
||||
if (_canMoveX || _canMoveY)
|
||||
{
|
||||
if (!_borderSmallIsLoaded)
|
||||
{
|
||||
_canvasSmallImg.Background = new VisualBrush(_imageMain);
|
||||
InitBorderSmall();
|
||||
_borderSmallIsLoaded = true;
|
||||
}
|
||||
ShowSmallImg = true;
|
||||
UpdateBorderSmall();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowSmallImg = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化右下角小图片
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新右下角小图片
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缩放图片
|
||||
/// </summary>
|
||||
/// <param name="isEnlarge"></param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 旋转图片
|
||||
/// </summary>
|
||||
/// <param name="rotate"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动图片
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动小图片
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<Brush>(ResourceToken.PrimaryBrush)
|
||||
};
|
||||
window.Background = ResourceHelper.GetResource<Brush>(ResourceToken.PrimaryBrush);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<Compile Include="Controls\Clock\Clock.cs" />
|
||||
<Compile Include="Controls\Clock\ClockRadioButton.cs" />
|
||||
<Compile Include="Controls\Growl.cs" />
|
||||
<Compile Include="Controls\ImageViewer.cs" />
|
||||
<Compile Include="Controls\Input\IDataInput.cs" />
|
||||
<Compile Include="Controls\Input\TextBox.cs" />
|
||||
<Compile Include="Controls\ISingleOpen.cs" />
|
||||
@@ -400,6 +401,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Themes\Styles\ImageViewer.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Themes\Styles\Label.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls"
|
||||
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Button.xaml"/>
|
||||
<ResourceDictionary Source="TextBlock.xaml"/>
|
||||
<ResourceDictionary Source="Border.xaml"/>
|
||||
<ResourceDictionary Source="ToggleButton.xaml"/>
|
||||
<ResourceDictionary Source="../Basic/Converters.xaml"/>
|
||||
<ResourceDictionary Source="../Basic/Paths.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style TargetType="controls:ImageViewer">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="MinWidth" Value="400"/>
|
||||
<Setter Property="MinHeight" Value="250"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="controls:ImageViewer">
|
||||
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid x:Name="PART_GridMain" ClipToBounds="True" Grid.RowSpan="2">
|
||||
<Border HorizontalAlignment="Left" VerticalAlignment="Top" Height="{TemplateBinding ImageHeight}" Width="{TemplateBinding ImageWidth}" Margin="{TemplateBinding ImageMargin}">
|
||||
<Image Name="PART_ImageMain" RenderTransformOrigin="0.5,0.5" Source="{TemplateBinding ImageSource}">
|
||||
<Image.LayoutTransform>
|
||||
<RotateTransform Angle="{Binding ImageRotate,RelativeSource={RelativeSource TemplatedParent}}"/>
|
||||
</Image.LayoutTransform>
|
||||
</Image>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Border Grid.Row="0" Grid.RowSpan="2" Width="252" Height="162" HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="{DynamicResource DarkOpacityBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1">
|
||||
<Border.Visibility>
|
||||
<MultiBinding Converter="{StaticResource BooleanArr2VisibilityConverter}">
|
||||
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="ShowSmallImgInternal"/>
|
||||
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="ShowImgMap"/>
|
||||
</MultiBinding>
|
||||
</Border.Visibility>
|
||||
<Canvas ClipToBounds="True" Name="PART_CanvasSmallImg" MaxWidth="250" MaxHeight="160">
|
||||
<Border UseLayoutRounding="True" Name="PART_BorderMove" Background="Transparent" Width="50" Height="70" BorderThickness="1" BorderBrush="Black">
|
||||
<Border BorderThickness="1" BorderBrush="White"/>
|
||||
</Border>
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Border UseLayoutRounding="True" Name="PART_BorderBottom" Opacity="0" CornerRadius="4,4,0,0" Grid.Row="1" HorizontalAlignment="Center" Background="{DynamicResource DarkOpacityBrush}">
|
||||
<StackPanel Margin="30,10" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<Button Command="interactivity:ControlCommands.Save" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource SaveGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.Open" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource WindowsGeometry}" Padding="3"/>
|
||||
|
||||
<Border Margin="10,2" Background="White" Style="{StaticResource BorderVerticallySplitter}"/>
|
||||
|
||||
<Button Command="interactivity:ControlCommands.Reduce" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource ReduceGeometry}" Padding="3"/>
|
||||
<TextBlock Margin="6,0" Text="{TemplateBinding ScaleStr}" Style="{StaticResource TextBlockSubTitle}" Foreground="{DynamicResource TextIconBrush}"/>
|
||||
<Button Command="interactivity:ControlCommands.Enlarge" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource EnlargeGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.Restore" Background="Transparent" Margin="6,0" Style="{StaticResource ButtonCustom}" Foreground="White">
|
||||
<Border BorderThickness="1" BorderBrush="White" Padding="2">
|
||||
<TextBlock Text="1:1"/>
|
||||
</Border>
|
||||
</Button>
|
||||
<Border Margin="10,2" Background="White" Style="{StaticResource BorderVerticallySplitter}"/>
|
||||
<Button Command="interactivity:ControlCommands.RotateLeft" CommandParameter="" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource RotateLeftGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.RotateRight" Margin="6,0,0,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource RotateLeftGeometry}" Padding="3" RenderTransformOrigin="0.5,0.5">
|
||||
<Button.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform ScaleY="1" ScaleX="-1"/>
|
||||
</TransformGroup>
|
||||
</Button.RenderTransform>
|
||||
</Button>
|
||||
<ToggleButton Visibility="{TemplateBinding ShowFullScreenButton,Converter={StaticResource Boolean2VisibilityConverter}}" Foreground="{DynamicResource TextIconBrush}" IsChecked="{Binding IsFullScreen,RelativeSource={RelativeSource FindAncestor,AncestorType=controls:ImageBrowser},Mode=TwoWay}" Margin="12,0,6,0" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.Geometry="{StaticResource FullScreenGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource FullScreenReturnGeometry}" Padding="3"/>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -37,6 +37,7 @@
|
||||
<ResourceDictionary Source="TransitioningContentControl.xaml"/>
|
||||
<ResourceDictionary Source="Image.xaml"/>
|
||||
<ResourceDictionary Source="Label.xaml"/>
|
||||
<ResourceDictionary Source="ImageViewer.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -195,63 +195,42 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="controls:ImageBrowser">
|
||||
<ControlTemplate.Resources>
|
||||
<Storyboard x:Key="Storyboard1">
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_GridTop">
|
||||
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<Storyboard x:Key="Storyboard2">
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_GridTop">
|
||||
<EasingDoubleKeyFrame KeyTime="0:0:.4" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</ControlTemplate.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid x:Name="PART_GridMain" ClipToBounds="True" Grid.RowSpan="2" Background="#dd000000">
|
||||
<Border HorizontalAlignment="Left" VerticalAlignment="Top" Height="{TemplateBinding ImageHeight}" Width="{TemplateBinding ImageWidth}" Margin="{TemplateBinding ImageMargin}">
|
||||
<Image Name="PART_ImageMain" RenderTransformOrigin="0.5,0.5" Source="{TemplateBinding ImageSource}">
|
||||
<Image.LayoutTransform>
|
||||
<RotateTransform Angle="{Binding ImageRotate,RelativeSource={RelativeSource TemplatedParent}}"/>
|
||||
</Image.LayoutTransform>
|
||||
</Image>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Border Visibility="{TemplateBinding ShowSmallImg,Converter={StaticResource Boolean2VisibilityConverter}}" Grid.Row="0" Grid.RowSpan="2" Width="252" Height="162" HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="{DynamicResource DarkOpacityBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1">
|
||||
<Canvas ClipToBounds="True" Name="PART_CanvasSmallImg" MaxWidth="250" MaxHeight="160">
|
||||
<Border UseLayoutRounding="True" Name="PART_BorderMove" Background="Transparent" Width="50" Height="70" BorderThickness="1" BorderBrush="Black">
|
||||
<Border BorderThickness="1" BorderBrush="White"/>
|
||||
</Border>
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Border UseLayoutRounding="True" Name="PART_BorderBottom" Opacity="0" CornerRadius="4,4,0,0" Grid.Row="1" HorizontalAlignment="Center" Background="{DynamicResource DarkOpacityBrush}">
|
||||
<StackPanel Margin="30,10" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<Button Command="interactivity:ControlCommands.Save" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource SaveGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.Open" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource WindowsGeometry}" Padding="3"/>
|
||||
|
||||
<Border Margin="10,2" Style="{StaticResource BorderVerticallySplitter}"/>
|
||||
|
||||
<Button Command="interactivity:ControlCommands.Reduce" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource ReduceGeometry}" Padding="3"/>
|
||||
<TextBlock Margin="6,0" Text="{TemplateBinding ScaleStr}" Style="{StaticResource TextBlockSubTitle}" Foreground="{DynamicResource TextIconBrush}"/>
|
||||
<Button Command="interactivity:ControlCommands.Enlarge" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource EnlargeGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.Restore" Background="Transparent" Margin="6,0" Style="{StaticResource ButtonCustom}" Foreground="White">
|
||||
<Border BorderThickness="1" BorderBrush="White" Padding="2">
|
||||
<TextBlock Text="1:1"/>
|
||||
</Border>
|
||||
</Button>
|
||||
<Border Margin="10,2" Style="{StaticResource BorderVerticallySplitter}"/>
|
||||
<Button Command="interactivity:ControlCommands.RotateLeft" CommandParameter="" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource RotateLeftGeometry}" Padding="3"/>
|
||||
<Button Command="interactivity:ControlCommands.RotateRight" Margin="6,0" Style="{StaticResource ButtonIcon}" controls:IconElement.Geometry="{StaticResource RotateLeftGeometry}" Padding="3" RenderTransformOrigin="0.5,0.5">
|
||||
<Button.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform ScaleY="1" ScaleX="-1"/>
|
||||
</TransformGroup>
|
||||
</Button.RenderTransform>
|
||||
</Button>
|
||||
<ToggleButton Foreground="{DynamicResource TextIconBrush}" IsChecked="{Binding IsFullScreen,RelativeSource={RelativeSource FindAncestor,AncestorType=controls:ImageBrowser},Mode=TwoWay}" Margin="6,0" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.Geometry="{StaticResource FullScreenGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource FullScreenReturnGeometry}" Padding="3"/>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<controls:ImageViewer x:Name="PART_ImageViewer" ShowImgMap="True" BorderThickness="0" Background="#dd000000"/>
|
||||
<Grid Name="PART_GridTop" Opacity="0" Background="{DynamicResource DarkOpacityBrush}" VerticalAlignment="Top" Grid.Row="0">
|
||||
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<TextBlock Text="{TemplateBinding ImgPath}" Foreground="White" Margin="10,0,0,0"/>
|
||||
<TextBlock Text="{TemplateBinding ImgSize,Converter={StaticResource Long2FileSizeConverter}}" Foreground="White" Margin="30,0,0,0"/>
|
||||
<TextBlock Text="{Binding ImgPath,ElementName=PART_ImageViewer}" Foreground="White" Margin="10,0,0,0"/>
|
||||
<TextBlock Text="{Binding ImgSize,ElementName=PART_ImageViewer,Converter={StaticResource Long2FileSizeConverter}}" Foreground="White" Margin="30,0,0,0"/>
|
||||
</StackPanel>
|
||||
<Button Command="interactivity:ControlCommands.Close" WindowChrome.IsHitTestVisibleInChrome="True" Background="Red" Grid.Row="0" Padding="14" controls:IconElement.Geometry="{StaticResource DeleteGeometry}" Style="{StaticResource ButtonIcon}" HorizontalAlignment="Right" VerticalAlignment="Top" Width="40" Height="40"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger SourceName="PART_ImageViewer" Property="ShowCloseButton" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard Storyboard="{StaticResource Storyboard2}"/>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
DataContext="{Binding ImageBrowserDemo,Source={StaticResource Locator}}"
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
|
||||
<controls:TransitioningContentControl>
|
||||
<Button Command="{Binding OpenImgCmd}" Content="{x:Static langs:Lang.OpenImageBrowser}" Style="{StaticResource ButtonPrimary}" Margin="32" VerticalAlignment="Center"/>
|
||||
<StackPanel Margin="32">
|
||||
<controls:ImageViewer Background="{DynamicResource BackgroundBrush}" Width="600" Height="330" ImageSource="/HandyControlDemo;component/Resources/Img/1.jpg"/>
|
||||
<Button Margin="0,32,0,0" Command="{Binding OpenImgCmd}" Content="{x:Static langs:Lang.OpenImageBrowser}" Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</controls:TransitioningContentControl>
|
||||
</UserControl>
|
||||
@@ -154,7 +154,7 @@
|
||||
<Image Source="../../Resources/Img/LeftMainContent/TimePicker_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.StepBarDemoCtl}" Content="{x:Static langs:Lang.StepBar}">
|
||||
<ListBoxItem Tag="{x:Static data:MessageToken.StepBarDemoCtl}" Content="{x:Static langs:Lang.StepBar}">
|
||||
<controls:EdgeElement.LeftContent>
|
||||
<Image Source="../../Resources/Img/LeftMainContent/Flow_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
@@ -169,7 +169,7 @@
|
||||
<Image Source="../../Resources/Img/LeftMainContent/Loading_Blue_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static data:MessageToken.ImageBrowserDemoCtl}" Content="{x:Static langs:Lang.ImageBrowser}">
|
||||
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.ImageBrowserDemoCtl}" Content="{x:Static langs:Lang.ImageBrowser}">
|
||||
<controls:EdgeElement.LeftContent>
|
||||
<Image Source="../../Resources/Img/LeftMainContent/ImageBrowser_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
|
||||
Reference in new issue
Block a user