From 08ae754ea34678222260a1a5eedb3ed3deb69faf Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Mon, 2 Mar 2020 23:27:22 +0800 Subject: [PATCH 1/8] add ManualObservableCollection --- .../Controls/NotifyIconDemoCtl.xaml | 34 ++-- .../UserControl/Controls/SideMenuDemoCtl.xaml | 12 +- .../UserControl/Main/LeftMainContent.xaml | 12 +- .../ManualObservableCollection!1.cs | 191 ++++++++++++++++++ .../HandyControl_Shared.projitems | 1 + 5 files changed, 218 insertions(+), 32 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Collections/ManualObservableCollection!1.cs diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml index 173073e2..36c6aeac 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml @@ -3,8 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs" xmlns:hc="https://handyorg.github.io/handycontrol" - xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" - xmlns:command="http://www.galasoft.ch/mvvmlight" xmlns:data="clr-namespace:HandyControlDemo.Data" DataContext="{Binding NotifyIconDemo,Source={StaticResource Locator}}" Background="{DynamicResource RegionBrush}"> @@ -47,14 +45,14 @@ - - - - - - - - + + + + + + + + @@ -68,14 +66,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/SideMenuDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/SideMenuDemoCtl.xaml index 2b2ae21d..2672b5a2 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/SideMenuDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/SideMenuDemoCtl.xaml @@ -2,18 +2,16 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:hc="https://handyorg.github.io/handycontrol" - xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" - xmlns:command="http://www.galasoft.ch/mvvmlight" DataContext="{Binding SideMenuDemo,Source={StaticResource Locator}}" Background="{DynamicResource RegionBrush}"> - - - - - + + + + + diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml index 909f10d9..775e9bc3 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml @@ -1,6 +1,4 @@  - - - - - + + + + + \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Collections/ManualObservableCollection!1.cs b/src/Shared/HandyControl_Shared/Collections/ManualObservableCollection!1.cs new file mode 100644 index 00000000..39abfc7e --- /dev/null +++ b/src/Shared/HandyControl_Shared/Collections/ManualObservableCollection!1.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; + +namespace HandyControl.Collections +{ + [Serializable] + public class ManualObservableCollection : Collection, INotifyCollectionChanged, INotifyPropertyChanged + { + private SimpleMonitor _monitor = new SimpleMonitor(); + + private const string CountString = "Count"; + + private const string IndexerName = "Item[]"; + + private bool _canNotify = true; + + public bool CanNotify + { + get => _canNotify; + set + { + _canNotify = value; + + if (value) + { + if (_oldCount != Count) + { + OnPropertyChanged(CountString); + } + + OnPropertyChanged(IndexerName); + OnCollectionReset(); + } + else + { + _oldCount = Count; + } + } + } + + private int _oldCount; + + public event NotifyCollectionChangedEventHandler CollectionChanged; + + public event PropertyChangedEventHandler PropertyChanged; + + public ManualObservableCollection() + { + + } + + // ReSharper disable once AssignNullToNotNullAttribute + public ManualObservableCollection(List list) : base(list != null ? new List(list.Count) : list) => CopyFrom(list); + + public ManualObservableCollection(IEnumerable collection) + { + if (collection == null) throw new ArgumentNullException(nameof(collection)); + CopyFrom(collection); + } + + private void CopyFrom(IEnumerable collection) + { + var items = Items; + if (collection != null) + { + using var enumerator = collection.GetEnumerator(); + while (enumerator.MoveNext()) + { + items.Add(enumerator.Current); + } + } + } + + public void Move(int oldIndex, int newIndex) => MoveItem(oldIndex, newIndex); + + protected override void ClearItems() + { + CheckReentrancy(); + base.ClearItems(); + OnPropertyChanged(CountString); + OnPropertyChanged(IndexerName); + OnCollectionReset(); + } + + protected override void RemoveItem(int index) + { + CheckReentrancy(); + var removedItem = this[index]; + + base.RemoveItem(index); + + OnPropertyChanged(CountString); + OnPropertyChanged(IndexerName); + OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index); + } + + protected override void InsertItem(int index, T item) + { + CheckReentrancy(); + base.InsertItem(index, item); + + OnPropertyChanged(CountString); + OnPropertyChanged(IndexerName); + OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); + } + + protected override void SetItem(int index, T item) + { + CheckReentrancy(); + var originalItem = this[index]; + base.SetItem(index, item); + + OnPropertyChanged(IndexerName); + OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index); + } + + protected virtual void MoveItem(int oldIndex, int newIndex) + { + CheckReentrancy(); + + var removedItem = this[oldIndex]; + + base.RemoveItem(oldIndex); + base.InsertItem(newIndex, removedItem); + + OnPropertyChanged(IndexerName); + OnCollectionChanged(NotifyCollectionChangedAction.Move, removedItem, newIndex, oldIndex); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (!CanNotify || PropertyChanged == null) return; + + PropertyChanged.Invoke(this, e); + } + + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (!CanNotify || CollectionChanged == null) return; + + using (BlockReentrancy()) + { + // ReSharper disable once PossibleNullReferenceException + CollectionChanged(this, e); + } + } + + protected IDisposable BlockReentrancy() + { + _monitor.Enter(); + return _monitor; + } + + protected void CheckReentrancy() + { + if (_monitor.Busy && CollectionChanged != null && CollectionChanged.GetInvocationList().Length > 1) + { + throw new InvalidOperationException("ObservableCollectionReentrancyNotAllowed"); + } + } + + private void OnPropertyChanged(string propertyName) => + OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) => + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex) => + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex)); + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) => + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); + + private void OnCollectionReset() => + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + + private class SimpleMonitor : IDisposable + { + public void Enter() => ++_busyCount; + + public void Dispose() => --_busyCount; + + public bool Busy => _busyCount > 0; + + private int _busyCount; + } + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 8e5bce5f..1bad34b4 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -9,6 +9,7 @@ HandyControl + From 46b1297aa7d911ce56207b8d1fcb19c6df5d4f2f Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Fri, 6 Mar 2020 14:36:12 +0800 Subject: [PATCH 2/8] add Screenshot --- .../HandyControlDemo_Shared/App.xaml.cs | 1 - .../UserControl/Controls/PoptipDemoCtl.xaml | 6 +- .../Controls/Attach/TipElement.cs | 6 +- .../Controls/ColorPicker/ColorDropper.cs | 2 +- .../Controls/Other/Poptip.cs | 46 +- .../Controls/Screenshot/Screenshot.cs | 16 + .../Controls/Screenshot/ScreenshotWindow.cs | 572 ++++++++++++++++++ .../Data/Args/MouseHookEventArgs.cs | 2 +- .../Data/Enum/PlacementType.cs | 66 ++ .../Data/Enum/TipPlacement.cs | 2 +- .../HandyControl_Shared/Data/ResourceToken.cs | 4 +- .../HandyControl_Shared.projitems | 22 +- .../{ => Behavior}/Behavior!1.cs | 0 .../Interactivity/{ => Behavior}/Behavior.cs | 0 .../{ => Behavior}/BehaviorCollection.cs | 0 .../{ => Behavior}/FluidMoveBehavior.cs | 0 .../{ => Behavior}/FluidMoveBehaviorBase.cs | 0 .../MouseDragElementBehavior.cs | 0 .../MouseDragElementBehaviorEx.cs | 0 .../Themes/Styles/Screenshot.xaml | 125 ++++ .../Themes/Styles/Style.xaml | 1 + .../Tools/GlobalShortcut.cs | 19 +- .../Tools/Helper/WindowHelper.cs | 1 - .../Tools/Hook/ClipboardHook.cs | 31 +- .../Tools/Hook/KeyboardHook.cs | 35 +- .../Tools/Hook/MouseHook.cs | 37 +- .../Tools/Interop/InteropMethods.cs | 18 +- .../Tools/Interop/InteropValues.cs | 11 +- 28 files changed, 923 insertions(+), 100 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Controls/Screenshot/Screenshot.cs create mode 100644 src/Shared/HandyControl_Shared/Controls/Screenshot/ScreenshotWindow.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Enum/PlacementType.cs rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/Behavior!1.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/Behavior.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/BehaviorCollection.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/FluidMoveBehavior.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/FluidMoveBehaviorBase.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/MouseDragElementBehavior.cs (100%) rename src/Shared/HandyControl_Shared/Interactivity/{ => Behavior}/MouseDragElementBehaviorEx.cs (100%) create mode 100644 src/Shared/HandyControl_Shared/Themes/Styles/Screenshot.xaml diff --git a/src/Shared/HandyControlDemo_Shared/App.xaml.cs b/src/Shared/HandyControlDemo_Shared/App.xaml.cs index 6cc43843..05d65336 100644 --- a/src/Shared/HandyControlDemo_Shared/App.xaml.cs +++ b/src/Shared/HandyControlDemo_Shared/App.xaml.cs @@ -7,7 +7,6 @@ using System.Runtime; using System.Security.Authentication; using System.Threading; using System.Windows; -using System.Windows.Media.Animation; using HandyControl.Data; using HandyControl.Tools; using HandyControlDemo.Data; diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PoptipDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PoptipDemoCtl.xaml index 43d45e3e..30891034 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PoptipDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PoptipDemoCtl.xaml @@ -36,12 +36,12 @@