diff --git a/README.md b/README.md index b29f80ff..a00fe919 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ Step 4:enjoy coding ## Latest examples +### ImageBlock + +![ImageBlock](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/ImageBlock.gif) + +![ImageBlock](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/ImageBlock.png) + ### Magnifier ![Magnifier](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Magnifier.png) @@ -75,6 +81,8 @@ Step 4:enjoy coding ![ButtonGroup](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/ButtonGroup.png) +## History publication + ### Grid ![Grid](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Grid.gif) @@ -83,8 +91,6 @@ Step 4:enjoy coding ![SideMenu](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/SideMenu.png) -## History publication - ### NotifyIcon ![NotifyIcon](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/NotifyIcon.png) diff --git a/Resources/ImageBlock.gif b/Resources/ImageBlock.gif new file mode 100644 index 00000000..d64e99d5 Binary files /dev/null and b/Resources/ImageBlock.gif differ diff --git a/Resources/ImageBlock.png b/Resources/ImageBlock.png new file mode 100644 index 00000000..4157f8a2 Binary files /dev/null and b/Resources/ImageBlock.png differ diff --git a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj index f9dad817..ffdca70a 100644 --- a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj +++ b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj @@ -5,7 +5,7 @@ true HandyControlDemo HandyControlDemo - 2.0.0 + 2.1.0 ..\..\Shared\HandyControlDemo_Shared\Resources\Img\icon.ico Debug;Release Copyright © HandyOrg 2018-2019 @@ -359,6 +359,12 @@ Resources\Img\LeftMainContent\VSO_Card_16x.png + + Resources\Img\LeftMainContent\ImageStack_16x.png + + + Resources\Img\Dance.png + diff --git a/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj b/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj index 34c1ddeb..36811f33 100644 --- a/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj +++ b/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj @@ -4,7 +4,7 @@ true HandyControl HandyControl - 2.0.0 + 2.1.0 2.0.0.0 false false diff --git a/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj b/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj index 39ce5905..b4a33b11 100644 --- a/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj +++ b/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj @@ -396,6 +396,12 @@ TextTemplatingFileGenerator MessageToken.cs + + Resources\Img\Dance.png + + + Resources\Img\LeftMainContent\ImageStack_16x.png + Resources\Img\LeftMainContent\VSO_Card_16x.png diff --git a/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj b/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj index b78eac34..e568c938 100644 --- a/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj +++ b/src/Net_GE45/HandyControlDemo_Net_GE45/HandyControlDemo_Net_GE45.csproj @@ -458,6 +458,12 @@ TextTemplatingFileGenerator MessageToken.cs + + Resources\Img\Dance.png + + + Resources\Img\LeftMainContent\ImageStack_16x.png + Resources\Img\LeftMainContent\VSO_Card_16x.png diff --git a/src/Shared/HandyControlDemo_Shared/Data/MessageToken.cs b/src/Shared/HandyControlDemo_Shared/Data/MessageToken.cs index 81f4aaab..2c3e791a 100644 --- a/src/Shared/HandyControlDemo_Shared/Data/MessageToken.cs +++ b/src/Shared/HandyControlDemo_Shared/Data/MessageToken.cs @@ -104,6 +104,8 @@ public static readonly string MagnifierDemoCtl = nameof(MagnifierDemoCtl); + public static readonly string ImageBlockDemoCtl = nameof(ImageBlockDemoCtl); + public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl); public static readonly string RepeatButtonDemoCtl = nameof(RepeatButtonDemoCtl); diff --git a/src/Shared/HandyControlDemo_Shared/Data/MessageToken.tt b/src/Shared/HandyControlDemo_Shared/Data/MessageToken.tt index 9dd5242f..c5d3944e 100644 --- a/src/Shared/HandyControlDemo_Shared/Data/MessageToken.tt +++ b/src/Shared/HandyControlDemo_Shared/Data/MessageToken.tt @@ -54,7 +54,8 @@ var controlList = new List "RangeSliderDemoCtl", "ButtonGroupDemoCtl", "CardDemoCtl", - "MagnifierDemoCtl" + "MagnifierDemoCtl", + "ImageBlockDemoCtl" }; var styleList = new List { diff --git a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems index 29c71932..8c3ece37 100644 --- a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems +++ b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems @@ -54,6 +54,9 @@ CardDemoCtl.xaml + + ImageBlockDemoCtl.xaml + MagnifierDemoCtl.xaml @@ -423,6 +426,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/Shared/HandyControlDemo_Shared/Properties/AssemblyInfo.cs b/src/Shared/HandyControlDemo_Shared/Properties/AssemblyInfo.cs index e13e70bb..d7e7e5cc 100644 --- a/src/Shared/HandyControlDemo_Shared/Properties/AssemblyInfo.cs +++ b/src/Shared/HandyControlDemo_Shared/Properties/AssemblyInfo.cs @@ -13,5 +13,5 @@ using System.Windows; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -[assembly: AssemblyVersion("2.0.0")] +[assembly: AssemblyVersion("2.1.0")] #endif \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs index 510ba758..ce60584b 100644 --- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs +++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs @@ -690,6 +690,15 @@ namespace HandyControlDemo.Properties.Langs { } } + /// + /// 查找类似 图片块 的本地化字符串。 + /// + public static string ImageBlock { + get { + return ResourceManager.GetString("ImageBlock", resourceCulture); + } + } + /// /// 查找类似 图片浏览器 的本地化字符串。 /// diff --git a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx index fcdb3a41..824b75e4 100644 --- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx +++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx @@ -630,4 +630,7 @@ Magnifier + + ImageBlock + \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx index 9b30e734..2cc4d56b 100644 --- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx +++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx @@ -630,4 +630,7 @@ 放大镜 + + 图片块 + \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/Resources/Img/Dance.png b/src/Shared/HandyControlDemo_Shared/Resources/Img/Dance.png new file mode 100644 index 00000000..65b367fb Binary files /dev/null and b/src/Shared/HandyControlDemo_Shared/Resources/Img/Dance.png differ diff --git a/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/ImageStack_16x.png b/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/ImageStack_16x.png new file mode 100644 index 00000000..62f6c66b Binary files /dev/null and b/src/Shared/HandyControlDemo_Shared/Resources/Img/LeftMainContent/ImageStack_16x.png differ diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml index a35701a0..0b4a7597 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml @@ -4,10 +4,6 @@ xmlns:hc="https://handyorg.github.io/handycontrol" Background="{DynamicResource RegionBrush}"> - - - - - + diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml new file mode 100644 index 00000000..e226326e --- /dev/null +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml.cs b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml.cs new file mode 100644 index 00000000..abf2962a --- /dev/null +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml.cs @@ -0,0 +1,10 @@ +namespace HandyControlDemo.UserControl +{ + public partial class ImageBlockDemoCtl + { + public ImageBlockDemoCtl() + { + InitializeComponent(); + } + } +} diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml index f4d14f70..2d8d68d4 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml @@ -195,6 +195,11 @@ + + + + + @@ -330,7 +335,7 @@ - + diff --git a/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs b/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs index 98557f94..e352119a 100644 --- a/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs +++ b/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs @@ -33,6 +33,22 @@ namespace HandyControl.Controls VisibilityProperty.OverrideMetadata(typeof(GifImage), new PropertyMetadata(default(Visibility), OnVisibilityChanged)); } + public static readonly DependencyProperty UriProperty = DependencyProperty.Register( + "Uri", typeof(Uri), typeof(GifImage), new PropertyMetadata(default(Uri), OnUriChanged)); + + private static void OnUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (GifImage) d; + var v = (Uri)e.NewValue; + ctl.Source = new BitmapImage(v); + } + + public Uri Uri + { + get => (Uri) GetValue(UriProperty); + set => SetValue(UriProperty, value); + } + private static void OnVisibilityChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) { var ctl = (GifImage)s; @@ -56,10 +72,14 @@ namespace HandyControl.Controls if (DesignerProperties.GetIsInDesignMode(this)) return; if (_isLoaded) return; _isLoaded = true; - if (Source is BitmapImage image) + if (Uri != null) { - var uri = image.UriSource; - GetGifStreamFromPack(uri); + GetGifStreamFromPack(Uri); + StartAnimate(); + } + else if (Source is BitmapImage image) + { + GetGifStreamFromPack(image.UriSource); StartAnimate(); } }; diff --git a/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs b/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs new file mode 100644 index 00000000..9b9b37b1 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs @@ -0,0 +1,178 @@ +using System; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Threading; +using HandyControl.Data; + +namespace HandyControl.Controls +{ + public class ImageBlock : FrameworkElement + { + private readonly DispatcherTimer _dispatcherTimer; + + private int _indexMax; + + private int _indexMin; + + private int _currentIndex; + + public ImageBlock() + { + _dispatcherTimer = new DispatcherTimer + { + Interval = Interval + }; + _dispatcherTimer.Tick += DispatcherTimer_Tick; + } + + private void OnPositionsChanged() + { + _indexMin = StartRow * Columns + StartColumn; + _indexMax = EndRow * Columns + EndColumn; + _currentIndex = _indexMin; + } + + private static void OnPositionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock)d; + ctl.OnPositionsChanged(); + } + + private void DispatcherTimer_Tick(object sender, EventArgs e) => InvalidateVisual(); + + public static readonly DependencyProperty StartColumnProperty = DependencyProperty.Register( + "StartColumn", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int StartColumn + { + get => (int) GetValue(StartColumnProperty); + set => SetValue(StartColumnProperty, value); + } + + public static readonly DependencyProperty StartRowProperty = DependencyProperty.Register( + "StartRow", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int StartRow + { + get => (int) GetValue(StartRowProperty); + set => SetValue(StartRowProperty, value); + } + + public static readonly DependencyProperty EndColumnProperty = DependencyProperty.Register( + "EndColumn", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int EndColumn + { + get => (int) GetValue(EndColumnProperty); + set => SetValue(EndColumnProperty, value); + } + + public static readonly DependencyProperty EndRowProperty = DependencyProperty.Register( + "EndRow", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int EndRow + { + get => (int) GetValue(EndRowProperty); + set => SetValue(EndRowProperty, value); + } + + public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register( + "IsPlaying", typeof(bool), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnIsPlayingChanged)); + + private static void OnIsPlayingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock)d; + if ((bool) e.NewValue) + { + ctl._dispatcherTimer.Start(); + } + else + { + ctl._dispatcherTimer.Stop(); + } + } + + public bool IsPlaying + { + get => (bool) GetValue(IsPlayingProperty); + set => SetValue(IsPlayingProperty, value); + } + + public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( + "Columns", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int1Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), obj => (int)obj >= 1); + + public int Columns + { + get => (int) GetValue(ColumnsProperty); + set => SetValue(ColumnsProperty, value); + } + + public static readonly DependencyProperty RowsProperty = DependencyProperty.Register( + "Rows", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int1Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), obj => (int)obj >= 1); + + public int Rows + { + get => (int) GetValue(RowsProperty); + set => SetValue(RowsProperty, value); + } + + public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register( + "Interval", typeof(TimeSpan), typeof(ImageBlock), new PropertyMetadata(TimeSpan.FromSeconds(1), OnIntervalChanged)); + + private static void OnIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock) d; + ctl._dispatcherTimer.Interval = (TimeSpan) e.NewValue; + } + + public TimeSpan Interval + { + get => (TimeSpan) GetValue(IntervalProperty); + set => SetValue(IntervalProperty, value); + } + + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( + "Source", typeof(ImageSource), typeof(ImageBlock), new FrameworkPropertyMetadata(default(ImageSource), + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender)); + + public ImageSource Source + { + get => (ImageSource)GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + + protected override void OnRender(DrawingContext dc) + { + if (Source != null && Source is BitmapSource source) + { + // ReSharper disable once AssignNullToNotNullAttribute + var croppedBitmap = new CroppedBitmap(source, CalDisplayRect()); + dc.DrawImage(croppedBitmap, new Rect(0, 0, RenderSize.Width, RenderSize.Height)); + } + } + + private Int32Rect CalDisplayRect() + { + if (_currentIndex > _indexMax) + { + _currentIndex = _indexMin; + } + + var x = (int) (_currentIndex % Columns * RenderSize.Width); + // ReSharper disable once PossibleLossOfFraction + var y = (int) (_currentIndex / Columns * RenderSize.Height); + + var rect = new Int32Rect(x, y, (int)RenderSize.Width, (int)RenderSize.Height); + _currentIndex++; + return rect; + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 95447ffc..bfb0b9f6 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -19,6 +19,7 @@ + diff --git a/src/Shared/HandyControl_Shared/Properties/AssemblyInfo.cs b/src/Shared/HandyControl_Shared/Properties/AssemblyInfo.cs index ebffaf6a..0be451ad 100644 --- a/src/Shared/HandyControl_Shared/Properties/AssemblyInfo.cs +++ b/src/Shared/HandyControl_Shared/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: AssemblyVersion("2.0.0")] +[assembly: AssemblyVersion("2.1.0")] #endif [assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Controls")]