diff --git a/README.md b/README.md
index 7c5f1c52..29fc1921 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,10 @@ Step 3:enjoy coding
## Latest examples
+### Grid
+
+
+
### SideMenu

@@ -70,12 +74,12 @@ Step 3:enjoy coding

+## History publication
+
### Badge

-## History publication
-
### Gravatar

diff --git a/Resources/Grid.gif b/Resources/Grid.gif
new file mode 100644
index 00000000..9041b842
Binary files /dev/null and b/Resources/Grid.gif differ
diff --git a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj
index fdbd815d..f4e0039c 100644
--- a/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj
+++ b/src/Core_30/HandyControlDemo_Core_30/HandyControlDemo_Core30.csproj
@@ -315,6 +315,9 @@
Resources\Img\LeftMainContent\WindowsForm_16x.png
+
+ Resources\Img\LeftMainContent\GridPane_16x.png
+
Resources\Img\qq-group.jpg
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 2ac1874c..3f62846b 100644
--- a/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj
+++ b/src/Core_30/HandyControl_Core_30/HandyControl_Core_30.csproj
@@ -38,4 +38,9 @@
+
+
+ Resources\dropper.cur
+
+
\ No newline at end of file
diff --git a/src/Core_30/HandyControl_Core_30/Themes/Styles/Base/ComboBoxBaseStyle.xaml b/src/Core_30/HandyControl_Core_30/Themes/Styles/Base/ComboBoxBaseStyle.xaml
index 90d37234..29c6a7cd 100644
--- a/src/Core_30/HandyControl_Core_30/Themes/Styles/Base/ComboBoxBaseStyle.xaml
+++ b/src/Core_30/HandyControl_Core_30/Themes/Styles/Base/ComboBoxBaseStyle.xaml
@@ -887,6 +887,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1009,6 +1150,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 4e282a0d..f6f98c80 100644
--- a/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj
+++ b/src/Net_40/HandyControlDemo_Net_40/HandyControlDemo_Net_40.csproj
@@ -395,6 +395,9 @@
TextTemplatingFileGenerator
MessageToken.cs
+
+ Resources\Img\LeftMainContent\GridPane_16x.png
+
Resources\Img\LeftMainContent\MainMenuControl_16x.png
diff --git a/src/Net_40/HandyControl_Net_40/HandyControl_Net_40.csproj b/src/Net_40/HandyControl_Net_40/HandyControl_Net_40.csproj
index 71a3f961..b64921df 100644
--- a/src/Net_40/HandyControl_Net_40/HandyControl_Net_40.csproj
+++ b/src/Net_40/HandyControl_Net_40/HandyControl_Net_40.csproj
@@ -100,6 +100,11 @@
Lang.Designer.cs
+
+
+ Resources\dropper.cur
+
+
\ No newline at end of file
diff --git a/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/ComboBoxBaseStyle.xaml b/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/ComboBoxBaseStyle.xaml
index 5bb899f8..52ccd53e 100644
--- a/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/ComboBoxBaseStyle.xaml
+++ b/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/ComboBoxBaseStyle.xaml
@@ -824,6 +824,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -939,6 +1073,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj b/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj
index c989b1c4..fa66936d 100644
--- a/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj
+++ b/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj
@@ -141,6 +141,11 @@
Lang.Designer.cs
+
+
+ Resources\dropper.cur
+
+
\ No newline at end of file
diff --git a/src/Net_GE45/HandyControl_Net_GE45/Themes/Styles/Base/ComboBoxBaseStyle.xaml b/src/Net_GE45/HandyControl_Net_GE45/Themes/Styles/Base/ComboBoxBaseStyle.xaml
index 90d37234..29c6a7cd 100644
--- a/src/Net_GE45/HandyControl_Net_GE45/Themes/Styles/Base/ComboBoxBaseStyle.xaml
+++ b/src/Net_GE45/HandyControl_Net_GE45/Themes/Styles/Base/ComboBoxBaseStyle.xaml
@@ -887,6 +887,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1009,6 +1150,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems
index 7a9d0ef9..089614fe 100644
--- a/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems
+++ b/src/Shared/HandyControlDemo_Shared/HandyControlDemo_Shared.projitems
@@ -292,6 +292,7 @@
+
diff --git a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs
index 9d91fd32..6247b2cb 100644
--- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs
+++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.Designer.cs
@@ -114,6 +114,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 基础布局 的本地化字符串。
+ ///
+ public static string BasicLayout {
+ get {
+ return ResourceManager.GetString("BasicLayout", resourceCulture);
+ }
+ }
+
///
/// 查找类似 闪烁 的本地化字符串。
///
@@ -135,9 +144,9 @@ namespace HandyControlDemo.Properties.Langs {
///
/// 查找类似 边框 的本地化字符串。
///
- public static string Border1 {
+ public static string Border {
get {
- return ResourceManager.GetString("Border1", resourceCulture);
+ return ResourceManager.GetString("Border", resourceCulture);
}
}
@@ -276,6 +285,24 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 分栏偏移 的本地化字符串。
+ ///
+ public static string ColumnOffset {
+ get {
+ return ResourceManager.GetString("ColumnOffset", resourceCulture);
+ }
+ }
+
+ ///
+ /// 查找类似 分栏间隔 的本地化字符串。
+ ///
+ public static string ColumnSpacing {
+ get {
+ return ResourceManager.GetString("ColumnSpacing", resourceCulture);
+ }
+ }
+
///
/// 查找类似 组合框 的本地化字符串。
///
@@ -627,6 +654,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 混合布局 的本地化字符串。
+ ///
+ public static string HybridLayout {
+ get {
+ return ResourceManager.GetString("HybridLayout", resourceCulture);
+ }
+ }
+
///
/// 查找类似 忽略 的本地化字符串。
///
@@ -1086,6 +1122,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 响应式布局 的本地化字符串。
+ ///
+ public static string ResponsiveLayout {
+ get {
+ return ResourceManager.GetString("ResponsiveLayout", resourceCulture);
+ }
+ }
+
///
/// 查找类似 富文本框 的本地化字符串。
///
diff --git a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx
index 9807ecb7..2705cc41 100644
--- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx
+++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.en.resx
@@ -309,9 +309,6 @@
TreeView
-
- Border
-
ScrollViewer
@@ -585,4 +582,22 @@
Grid
+
+ Basic layout
+
+
+ Column spacing
+
+
+ Hybrid layout
+
+
+ Column offset
+
+
+ Responsive layout
+
+
+ Border
+
\ 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 0f5ce9d5..d10f5ec2 100644
--- a/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx
+++ b/src/Shared/HandyControlDemo_Shared/Properties/Langs/Lang.resx
@@ -309,7 +309,7 @@
树视图
-
+
边框
@@ -585,4 +585,19 @@
栅格
+
+ 基础布局
+
+
+ 分栏间隔
+
+
+ 混合布局
+
+
+ 分栏偏移
+
+
+ 响应式布局
+
\ No newline at end of file
diff --git a/src/Shared/HandyControlDemo_Shared/Service/DataService.cs b/src/Shared/HandyControlDemo_Shared/Service/DataService.cs
index 0e88b5a7..728a108e 100644
--- a/src/Shared/HandyControlDemo_Shared/Service/DataService.cs
+++ b/src/Shared/HandyControlDemo_Shared/Service/DataService.cs
@@ -72,7 +72,7 @@ namespace HandyControlDemo.Service
var list = new List();
for (var i = 1; i <= 9; i++)
{
- list.Add(converter.Convert(Properties.Langs.Lang.Text, null, i, CultureInfo.CurrentCulture)?.ToString());
+ list.Add($"{converter.Convert(Properties.Langs.Lang.Text, null, i, CultureInfo.CurrentCulture)}{i}");
}
return list;
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ClockDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ClockDemoCtl.xaml
index 43122db0..95fd9b50 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ClockDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ClockDemoCtl.xaml
@@ -4,6 +4,9 @@
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
Background="{DynamicResource RegionBrush}">
-
+
+
+
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ComboBoxDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ComboBoxDemoCtl.xaml
index 045e2025..efd9a0ad 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ComboBoxDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ComboBoxDemoCtl.xaml
@@ -15,12 +15,12 @@
-
+
-
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/CoverFlowDemoCtl.xaml.cs b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/CoverFlowDemoCtl.xaml.cs
index dc020673..e003022b 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/CoverFlowDemoCtl.xaml.cs
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/CoverFlowDemoCtl.xaml.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
namespace HandyControlDemo.UserControl
{
@@ -9,7 +8,7 @@ namespace HandyControlDemo.UserControl
{
InitializeComponent();
- CoverFlowMain.AddRange(new List
+ CoverFlowMain.AddRange(new []
{
new Uri(@"pack://application:,,,/Resources/Img/Album/1.jpg"),
new Uri(@"pack://application:,,,/Resources/Img/Album/2.jpg"),
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GridDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GridDemoCtl.xaml
index 5c0b25d0..f07af0f9 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GridDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GridDemoCtl.xaml
@@ -3,57 +3,153 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
xmlns:extension="clr-namespace:HandyControl.Tools.Extension;assembly=HandyControl"
+ xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
Background="{DynamicResource RegionBrush}">
-
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TabControlDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TabControlDemoCtl.xaml
index 5c54ea23..2b293612 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TabControlDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TabControlDemoCtl.xaml
@@ -2,12 +2,22 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="{DynamicResource RegionBrush}"
- xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
+ DataContext="{Binding TabControlDemo,Source={StaticResource Locator}}"
+ xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
+ xmlns:interactivity="clr-namespace:HandyControl.Interactivity;assembly=HandyControl">
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml
index 840acbb5..0c4355c8 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/TimePickerDemoCtl.xaml
@@ -17,7 +17,11 @@
-
+
+
+
+
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml
index a949e809..5ec9a609 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml
@@ -161,7 +161,7 @@
-
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml.cs b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml.cs
index 3eb55a71..f7a69289 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml.cs
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Main/LeftMainContent.xaml.cs
@@ -16,6 +16,13 @@ namespace HandyControlDemo.UserControl
public LeftMainContent()
{
InitializeComponent();
+
+ /*You have to ask me why I made Border special.
+ What drives me crazy is that if you don't do this,
+ the content of ListBoxItemBorder will always be 1 !
+ How amazing!
+ I wish someone could tell me why. */
+ ListBoxItemBorder.Content = Properties.Langs.Lang.Border;
}
private void TabControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Main/OverView.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Main/OverView.xaml
index 0a72a138..2cde78c4 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Main/OverView.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Main/OverView.xaml
@@ -26,7 +26,7 @@
-
+
diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Styles/ToggleButtonDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Styles/ToggleButtonDemoCtl.xaml
index f5680d6d..2a71ecd2 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Styles/ToggleButtonDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Styles/ToggleButtonDemoCtl.xaml
@@ -77,7 +77,7 @@
-
+
@@ -87,7 +87,7 @@
-
+
diff --git a/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/TabControlDemoViewModel.cs b/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/TabControlDemoViewModel.cs
new file mode 100644
index 00000000..d82c4254
--- /dev/null
+++ b/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/TabControlDemoViewModel.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Windows;
+using GalaSoft.MvvmLight;
+using HandyControl.Controls;
+using HandyControl.Data;
+#if netle40
+using GalaSoft.MvvmLight.Command;
+#else
+using GalaSoft.MvvmLight.CommandWpf;
+#endif
+
+namespace HandyControlDemo.ViewModel
+{
+ public class TabControlDemoViewModel : ViewModelBase
+ {
+ public RelayCommand ClosingCmd => new Lazy>(() =>
+ new RelayCommand(Closing)).Value;
+
+ private void Closing(CancelRoutedEventArgs args)
+ {
+ Growl.Info($"{(args.OriginalSource as TabItem)?.Header} Closing");
+ }
+
+ public RelayCommand ClosedCmd => new Lazy>(() =>
+ new RelayCommand(Closed)).Value;
+
+ private void Closed(RoutedEventArgs args)
+ {
+ Growl.Info($"{(args.OriginalSource as TabItem)?.Header} Closed");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControlDemo_Shared/ViewModel/ViewModelLocator.cs b/src/Shared/HandyControlDemo_Shared/ViewModel/ViewModelLocator.cs
index c3c84631..44d62f42 100644
--- a/src/Shared/HandyControlDemo_Shared/ViewModel/ViewModelLocator.cs
+++ b/src/Shared/HandyControlDemo_Shared/ViewModel/ViewModelLocator.cs
@@ -34,6 +34,7 @@ namespace HandyControlDemo.ViewModel
SimpleIoc.Default.Register();
SimpleIoc.Default.Register();
SimpleIoc.Default.Register();
+ SimpleIoc.Default.Register();
}
public static ViewModelLocator Instance => new Lazy(() =>
@@ -75,6 +76,8 @@ namespace HandyControlDemo.ViewModel
public SideMenuDemoViewModel SideMenuDemo => ServiceLocator.Current.GetInstance();
+ public TabControlDemoViewModel TabControlDemo => ServiceLocator.Current.GetInstance();
+
#endregion
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/StatusSwitchElement.cs b/src/Shared/HandyControl_Shared/Controls/Attach/StatusSwitchElement.cs
index 350c82d9..998c88d5 100644
--- a/src/Shared/HandyControl_Shared/Controls/Attach/StatusSwitchElement.cs
+++ b/src/Shared/HandyControl_Shared/Controls/Attach/StatusSwitchElement.cs
@@ -18,11 +18,11 @@ namespace HandyControl.Controls
///
/// 是否隐藏元素
///
- public static readonly DependencyProperty HiddenElementProperty = DependencyProperty.RegisterAttached(
- "HiddenElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(ValueBoxes.FalseBox));
+ public static readonly DependencyProperty HideUncheckedElementProperty = DependencyProperty.RegisterAttached(
+ "HideUncheckedElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(ValueBoxes.FalseBox));
- public static void SetHiddenElement(DependencyObject element, bool value) => element.SetValue(HiddenElementProperty, value);
+ public static void SetHideUncheckedElement(DependencyObject element, bool value) => element.SetValue(HideUncheckedElementProperty, value);
- public static bool GetHiddenElement(DependencyObject element) => (bool) element.GetValue(HiddenElementProperty);
+ public static bool GetHideUncheckedElement(DependencyObject element) => (bool) element.GetValue(HideUncheckedElementProperty);
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorDropper.cs b/src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorDropper.cs
new file mode 100644
index 00000000..dc9ecf92
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorDropper.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+using HandyControl.Data;
+using HandyControl.Tools;
+using HandyControl.Tools.Interop;
+
+namespace HandyControl.Controls
+{
+ internal class ColorDropper
+ {
+ private bool _cursorIsSetted;
+
+ private Cursor _dropperCursor;
+
+ private readonly ColorPicker _colorPicker;
+
+ public ColorDropper(ColorPicker colorPicker)
+ {
+ _colorPicker = colorPicker;
+ }
+
+ public void Update(bool isShow)
+ {
+ if (isShow)
+ {
+ if (_dropperCursor == null)
+ {
+ var info = Application.GetResourceStream(new Uri("pack://application:,,,/HandyControl;Component/Resources/dropper.cur"));
+ if (info != null)
+ {
+ _dropperCursor = new Cursor(info.Stream);
+ }
+ }
+
+ if (_dropperCursor == null) return;
+
+ MouseHook.Start();
+ MouseHook.StatusChanged += MouseHook_StatusChanged;
+ }
+ else
+ {
+ Mouse.OverrideCursor = Cursors.Arrow;
+ MouseHook.Stop();
+ MouseHook.StatusChanged -= MouseHook_StatusChanged;
+ }
+ }
+
+ private void MouseHook_StatusChanged(object sender, MouseHookEventArgs e)
+ {
+ var window = System.Windows.Window.GetWindow(_colorPicker);
+ if (window == null)
+ {
+ UpdateCursor(false);
+
+ return;
+ }
+
+ if (!_colorPicker.IsMouseOver && window.IsMouseOver)
+ {
+ UpdateCursor(true);
+ if (e.Message == MouseHookMessageType.LeftButtonDown)
+ {
+ var brush = new SolidColorBrush(GetColorAt(e.Point.X, e.Point.Y));
+ _colorPicker.SelectedBrush = brush;
+ }
+ }
+ else
+ {
+ UpdateCursor(false);
+ }
+ }
+
+ private void UpdateCursor(bool isDropper)
+ {
+ if (isDropper)
+ {
+ Mouse.Captured?.ReleaseMouseCapture();
+
+ if (!_cursorIsSetted)
+ {
+ Mouse.OverrideCursor = _dropperCursor;
+ _cursorIsSetted = true;
+ }
+ }
+ else
+ {
+ if (_cursorIsSetted)
+ {
+ Mouse.OverrideCursor = Cursors.Arrow;
+ _cursorIsSetted = false;
+ }
+ }
+ }
+
+ public static Color GetColorAt(int x, int y)
+ {
+ var desk = UnsafeNativeMethods.GetDesktopWindow();
+ var dc = UnsafeNativeMethods.GetWindowDC(desk);
+ var a = (int)UnsafeNativeMethods.GetPixel(dc, x, y);
+ UnsafeNativeMethods.ReleaseDC(desk, dc);
+ return Color.FromArgb(255, (byte) ((a >> 0) & 0xff), (byte) ((a >> 8) & 0xff), (byte) ((a >> 16) & 0xff));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/Other/ColorPicker.cs b/src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorPicker.cs
similarity index 93%
rename from src/Shared/HandyControl_Shared/Controls/Other/ColorPicker.cs
rename to src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorPicker.cs
index 96e2020d..1170a3f9 100644
--- a/src/Shared/HandyControl_Shared/Controls/Other/ColorPicker.cs
+++ b/src/Shared/HandyControl_Shared/Controls/ColorPicker/ColorPicker.cs
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Interactivity;
+using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
@@ -21,6 +23,7 @@ namespace HandyControl.Controls
[TemplatePart(Name = ElementSliderColor, Type = typeof(Panel))]
[TemplatePart(Name = ElementSliderOpacity, Type = typeof(Panel))]
[TemplatePart(Name = ElementPanelRgb, Type = typeof(Panel))]
+ [TemplatePart(Name = ElementButtonDropper, Type = typeof(ToggleButton))]
public class ColorPicker : Control, ISingleOpen
{
#region Constants
@@ -32,11 +35,16 @@ namespace HandyControl.Controls
private const string ElementSliderColor = "PART_SliderColor";
private const string ElementSliderOpacity = "PART_SliderOpacity";
private const string ElementPanelRgb = "PART_PanelRgb";
+ private const string ElementButtonDropper = "PART_ButtonDropper";
#endregion Constants
#region Data
+ private ColorDropper _colorDropper;
+
+ private ToggleButton _toggleButtonDropper;
+
private Panel _panelRgb;
private Border _borderColor;
@@ -53,6 +61,8 @@ namespace HandyControl.Controls
private bool _appliedTemplate;
+ private bool _disposed;
+
///
/// 当前显示的颜色类型
///
@@ -332,6 +342,11 @@ namespace HandyControl.Controls
}
}
+ ~ColorPicker()
+ {
+ Dispose(false);
+ }
+
public ColorPicker()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonConfirm_OnClick));
@@ -361,6 +376,11 @@ namespace HandyControl.Controls
_sliderOpacity.ValueChanged -= SliderOpacity_OnValueChanged;
}
+ if (_toggleButtonDropper != null)
+ {
+ _toggleButtonDropper.Click -= ToggleButtonDropper_Click;
+ }
+
_panelColor?.Children.Clear();
_panelRgb?.RemoveHandler(NumericUpDown.ValueChangedEvent, new EventHandler>(NumericUpDownRgb_OnValueChanged));
@@ -374,6 +394,7 @@ namespace HandyControl.Controls
_sliderColor = GetTemplateChild(ElementSliderColor) as Slider;
_sliderOpacity = GetTemplateChild(ElementSliderOpacity) as Slider;
_panelRgb = GetTemplateChild(ElementPanelRgb) as Panel;
+ _toggleButtonDropper = GetTemplateChild(ElementButtonDropper) as ToggleButton;
if (_sliderColor != null)
{
@@ -395,6 +416,11 @@ namespace HandyControl.Controls
collection.Add(behavior);
}
+ if (_toggleButtonDropper != null)
+ {
+ _toggleButtonDropper.Click += ToggleButtonDropper_Click;
+ }
+
_appliedTemplate = true;
if (_isLoaded)
{
@@ -428,7 +454,7 @@ namespace HandyControl.Controls
var button = new Button
{
Margin = new Thickness(0, 0, 12, 12),
- Style = FindResource("ButtonCustom") as Style,
+ Style = ResourceHelper.GetResource
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/ColorPicker.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/ColorPicker.xaml
index 63917319..a6b7748b 100644
--- a/src/Shared/HandyControl_Shared/Themes/Styles/ColorPicker.xaml
+++ b/src/Shared/HandyControl_Shared/Themes/Styles/ColorPicker.xaml
@@ -9,6 +9,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/ToggleButton.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/ToggleButton.xaml
index 2a26e635..2afe67cb 100644
--- a/src/Shared/HandyControl_Shared/Themes/Styles/ToggleButton.xaml
+++ b/src/Shared/HandyControl_Shared/Themes/Styles/ToggleButton.xaml
@@ -135,7 +135,7 @@
-
+
diff --git a/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs b/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs
index 17e2219c..84586d8c 100644
--- a/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs
+++ b/src/Shared/HandyControl_Shared/Tools/GifImageAnimator.cs
@@ -4,8 +4,9 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using HandyControl.Controls;
+using HandyControl.Data;
-namespace HandyControl.Data
+namespace HandyControl.Tools
{
internal class ImageAnimator
{
diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/ValidateHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/ValidateHelper.cs
index 4a0a94a6..ff69c094 100644
--- a/src/Shared/HandyControl_Shared/Tools/Helper/ValidateHelper.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Helper/ValidateHelper.cs
@@ -29,7 +29,7 @@
}
///
- /// 是否在正浮点数范围内
+ /// 是否在负浮点数范围内
///
///
///
diff --git a/src/Shared/HandyControl_Shared/Tools/Hook/MouseHook.cs b/src/Shared/HandyControl_Shared/Tools/Hook/MouseHook.cs
new file mode 100644
index 00000000..e7e2d0d1
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Tools/Hook/MouseHook.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using HandyControl.Data;
+using HandyControl.Tools.Interop;
+
+namespace HandyControl.Tools
+{
+ internal class MouseHook
+ {
+ public static event EventHandler StatusChanged;
+
+ private static IntPtr HookId = IntPtr.Zero;
+
+ private static readonly UnsafeNativeMethods.HookProc Proc = HookCallback;
+
+ public static void Start() => HookId = SetHook(Proc);
+
+ public static void Stop() => UnsafeNativeMethods.UnhookWindowsHookEx(HookId);
+
+ private static IntPtr SetHook(UnsafeNativeMethods.HookProc proc)
+ {
+ using (var curProcess = Process.GetCurrentProcess())
+ using (var curModule = curProcess.MainModule)
+ {
+ if (curModule != null)
+ {
+ return UnsafeNativeMethods.SetWindowsHookEx((int) UnsafeNativeMethods.HookType.WH_MOUSE_LL, proc,
+ UnsafeNativeMethods.GetModuleHandle(curModule.ModuleName), 0);
+ }
+ return IntPtr.Zero;
+ }
+ }
+
+ private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
+ {
+ if (nCode < 0) return UnsafeNativeMethods.CallNextHookEx(HookId, nCode, wParam, lParam);
+ var hookStruct = (UnsafeNativeMethods.MOUSEHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(UnsafeNativeMethods.MOUSEHOOKSTRUCT));
+ StatusChanged?.Invoke(null, new MouseHookEventArgs
+ {
+ Message = (MouseHookMessageType)wParam,
+ Point = new NativeMethods.POINT(hookStruct.pt.X, hookStruct.pt.Y)
+ });
+
+ return UnsafeNativeMethods.CallNextHookEx(HookId, nCode, wParam, lParam);
+ }
+ }
+}
diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs b/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs
index a88f2d1b..1c893525 100644
--- a/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Interop/UnsafeNativeMethods.cs
@@ -174,5 +174,45 @@ namespace HandyControl.Tools.Interop
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
+
+ [DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
+
+ [DllImport(ExternDll.Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr GetModuleHandle(string lpModuleName);
+
+ [DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern bool UnhookWindowsHookEx(IntPtr hhk);
+
+ public enum HookType
+ {
+ WH_MOUSE_LL = 14,
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MOUSEHOOKSTRUCT
+ {
+ public NativeMethods.POINT pt;
+ public IntPtr hwnd;
+ public uint wHitTestCode;
+ public IntPtr dwExtraInfo;
+ }
+
+ public delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);
+
+ [DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
+
+ [DllImport(ExternDll.User32, SetLastError = true)]
+ public static extern IntPtr GetDesktopWindow();
+
+ [DllImport(ExternDll.User32, SetLastError = true)]
+ public static extern IntPtr GetWindowDC(IntPtr window);
+
+ [DllImport(ExternDll.Gdi32, SetLastError = true)]
+ public static extern uint GetPixel(IntPtr dc, int x, int y);
+
+ [DllImport(ExternDll.User32, SetLastError = true)]
+ public static extern int ReleaseDC(IntPtr window, IntPtr dc);
}
}
\ No newline at end of file