diff --git a/README-zh.md b/README-zh.md
index a68750d3..a2981e41 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -118,6 +118,41 @@ xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
+----------
+### AnimatedGrid
+
+
+
+----------
+### GestureUnlock
+
+
+
+----------
+### IconicThumbnail
+
+
+
+----------
+### Snap
+
+
+
+----------
+### NavScrollPanel
+
+
+
+----------
+### Gauge
+
+
+
+----------
+### Message
+
+
+
----------
### DateRangePicker
diff --git a/README.md b/README.md
index c1c44374..7901815d 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,26 @@ xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
`xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"`
+----------
+### AnimatedGrid
+
+
+
+----------
+### GestureUnlock
+
+
+
+----------
+### IconicThumbnail
+
+
+
+----------
+### Snap
+
+
+
----------
### NavScrollPanel
diff --git a/src/Package.props b/src/Package.props
index 273f2326..2644d73e 100644
--- a/src/Package.props
+++ b/src/Package.props
@@ -7,9 +7,9 @@
true
snupkg
Copyright © WPFDevelopersOrg 2025
- 1.1.0.3
- 1.1.0.3
- 1.1.0.3
+ 0.0.0.2
+ 0.0.0.2
+ 0.0.0.2
https://github.com/WPFDevelopersOrg/WPFDevelopers
Debug;Release;Debug-.NET40;Release-.NET40
diff --git a/src/Resources.props b/src/Resources.props
index ac35ddcb..7ae435f6 100644
--- a/src/Resources.props
+++ b/src/Resources.props
@@ -75,6 +75,9 @@
Resources\Images\ZooSemy\1.png
+
+ Resources\Images\IconicThumbnail\%(Filename)%(Extension)
+
Resources\Audio\HelloWPFDevelopes_en.mp3
diff --git a/src/TargetFrameworks.props b/src/TargetFrameworks.props
index ea6ba3f9..68da39e9 100644
--- a/src/TargetFrameworks.props
+++ b/src/TargetFrameworks.props
@@ -17,7 +17,7 @@
7.0.0
- 7.0.0
+ 5.0.0
@@ -43,7 +43,7 @@
7.0.0
- 7.0.0
+ 4.7.0
\ No newline at end of file
diff --git a/src/WPFDevelopers.Net40/Themes/Generic.xaml b/src/WPFDevelopers.Net40/Themes/Generic.xaml
index 8fba6634..42892e77 100644
--- a/src/WPFDevelopers.Net40/Themes/Generic.xaml
+++ b/src/WPFDevelopers.Net40/Themes/Generic.xaml
@@ -17,7 +17,6 @@
-
@@ -27,11 +26,6 @@
-
-
-
-
+ Margin="0,0,-1,0"
+ HorizontalAlignment="Stretch"
+ Background="{TemplateBinding TitleBackground}" />
+
@@ -85,7 +81,7 @@
Orientation="Horizontal">
-
@@ -699,18 +698,14 @@
-
-
-
-
+
+
@@ -724,17 +719,17 @@
-
-
+
@@ -762,12 +757,12 @@
-
+
-
+
@@ -1406,16 +1401,16 @@
-
+
-
+
-
+
-
+
@@ -1496,6 +1491,7 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Net40/Window.cs b/src/WPFDevelopers.Net40/Window.cs
index 23e65028..5eecc53f 100644
--- a/src/WPFDevelopers.Net40/Window.cs
+++ b/src/WPFDevelopers.Net40/Window.cs
@@ -1,6 +1,8 @@
using Microsoft.Windows.Shell;
using System;
using System.Windows;
+using System.Windows.Automation.Peers;
+using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
@@ -8,16 +10,28 @@
using WPFDevelopers.Controls;
using WPFDevelopers.Core.Helpers;
using WPFDevelopers.Helpers;
-using static WPFDevelopers.Core.Helpers.MonitorHelper;
namespace WPFDevelopers.Net40
{
[TemplatePart(Name = TitleBarIcon, Type = typeof(Button))]
+ [TemplatePart(Name = HighTitleMaximizeButton, Type = typeof(Button))]
+ [TemplatePart(Name = HighTitleRestoreButton, Type = typeof(Button))]
+ [TemplatePart(Name = TitleBarMaximizeButton, Type = typeof(Button))]
+ [TemplatePart(Name = TitleBarRestoreButton, Type = typeof(Button))]
public class Window : System.Windows.Window
{
private const string TitleBarIcon = "PART_TitleBarIcon";
+ private const string HighTitleMaximizeButton = "PART_MaximizeButton";
+ private const string HighTitleRestoreButton = "PART_RestoreButton";
+ private const string TitleBarMaximizeButton = "PART_TitleBarMaximizeButton";
+ private const string TitleBarRestoreButton = "PART_TitleBarRestoreButton";
private WindowStyle _windowStyle;
private Button _titleBarIcon;
+ private Button _highTitleMaximizeButton;
+ private Button _highTitleRestoreButton;
+ private Button _titleBarMaximizeButton;
+ private Button _titleBarRestoreButton;
+ private IntPtr hWnd;
public static readonly DependencyProperty TitleHeightProperty =
DependencyProperty.Register("TitleHeight", typeof(double), typeof(Window), new PropertyMetadata(50d));
@@ -41,7 +55,6 @@ static Window()
public Window()
{
- Loaded += Window_Loaded;
WPFDevelopers.Resources.ThemeChanged += Resources_ThemeChanged;
CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow,
@@ -69,9 +82,12 @@ public override void OnApplyTemplate()
_titleBarIcon.MouseDoubleClick -= Icon_MouseDoubleClick;
_titleBarIcon.MouseDoubleClick += Icon_MouseDoubleClick;
}
+ _highTitleMaximizeButton = GetTemplateChild(HighTitleMaximizeButton) as Button;
+ _highTitleRestoreButton = GetTemplateChild(HighTitleRestoreButton) as Button;
+ _titleBarMaximizeButton = GetTemplateChild(TitleBarMaximizeButton) as Button;
+ _titleBarRestoreButton = GetTemplateChild(TitleBarRestoreButton) as Button;
}
-
private void Icon_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
@@ -108,8 +124,9 @@ public TitleBarMode TitleBarMode
set => SetValue(TitleBarModeProperty, value);
}
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ protected override void OnSourceInitialized(EventArgs e)
{
+ base.OnSourceInitialized(e);
hWnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hWnd).AddHook(WindowProc);
if (TitleBarMode == TitleBarMode.Normal)
@@ -152,7 +169,7 @@ private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
{
- SendMessage(hWnd, MonitorHelper.WindowsMessageCodes.WM_SYSCOMMAND, new IntPtr(MonitorHelper.WindowsMessageCodes.SC_MINIMIZE), IntPtr.Zero);
+ Win32.SendMessage(hWnd, WindowsMessageCodes.WM_SYSCOMMAND, new IntPtr(WindowsMessageCodes.SC_MINIMIZE), IntPtr.Zero);
}
private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
@@ -160,8 +177,7 @@ private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
SystemCommands.RestoreWindow(this);
}
- private IntPtr hWnd;
-
+
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
@@ -184,6 +200,75 @@ private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, re
handled = true;
}
break;
+ #region SnapLayouts
+ case WindowsMessageCodes.WM_NCHITTEST:
+ try
+ {
+ if (OSVersionHelper.IsSnapLayoutSupported() && ResizeMode != ResizeMode.NoResize && ResizeMode != ResizeMode.CanMinimize)
+ {
+ int x = lParam.ToInt32() & 0xffff;
+ int y = lParam.ToInt32() >> 16;
+ var dpiX = OSVersionHelper.DeviceUnitsScalingFactorX;
+ var button = TitleBarMode == TitleBarMode.Normal
+ ? (WindowState != WindowState.Maximized ? _titleBarMaximizeButton : _titleBarRestoreButton)
+ : (WindowState != WindowState.Maximized ? _highTitleMaximizeButton : _highTitleRestoreButton);
+ if (button != null)
+ {
+ var contentPresenter = button.Template.FindName("PART_ContentPresenter", button) as ContentPresenter;
+ if (contentPresenter != null)
+ {
+ var rect = new Rect(button.PointToScreen(new Point()), new Size(button.ActualWidth * dpiX, button.ActualHeight * dpiX));
+ if (rect.Contains(new Point(x, y)))
+ {
+ handled = true;
+ contentPresenter.Opacity = 1;
+ }
+ else
+ {
+ contentPresenter.Opacity = 0.7;
+ }
+ return new IntPtr(OSVersionHelper.HTMAXBUTTON);
+ }
+
+ }
+ }
+ }
+ catch (OverflowException)
+ {
+ handled = true;
+ }
+ break;
+ case WindowsMessageCodes.WM_NCLBUTTONDOWN:
+ if (OSVersionHelper.IsSnapLayoutSupported()
+ &&
+ (ResizeMode != ResizeMode.NoResize
+ ||
+ ResizeMode != ResizeMode.CanMinimize))
+ {
+ int x = lParam.ToInt32() & 0xffff;
+ int y = lParam.ToInt32() >> 16;
+ var dpiX = OSVersionHelper.DeviceUnitsScalingFactorX;
+ Button button = TitleBarMode == TitleBarMode.Normal
+ ? (WindowState != WindowState.Maximized ? _titleBarMaximizeButton : _titleBarRestoreButton)
+ : (WindowState != WindowState.Maximized ? _highTitleMaximizeButton : _highTitleRestoreButton);
+ if (button != null)
+ {
+ var rect = new Rect(button.PointToScreen(
+ new Point()),
+ new Size(button.ActualWidth * dpiX, button.ActualHeight * dpiX));
+ if (rect.Contains(new Point(x, y)))
+ {
+ handled = true;
+ IInvokeProvider invokeProv = new ButtonAutomationPeer(button).GetPattern(PatternInterface.Invoke) as IInvokeProvider;
+ invokeProv?.Invoke();
+ }
+ }
+ }
+ break;
+ #endregion
+ default:
+ handled = false;
+ break;
}
return IntPtr.Zero;
}
diff --git a/src/WPFDevelopers.Net45x/Styles/Styles.TreeView.xaml b/src/WPFDevelopers.Net45x/Styles/Styles.TreeView.xaml
index bd2ac6d8..1073206e 100644
--- a/src/WPFDevelopers.Net45x/Styles/Styles.TreeView.xaml
+++ b/src/WPFDevelopers.Net45x/Styles/Styles.TreeView.xaml
@@ -157,13 +157,6 @@
-
-
-
-
-
-
-
@@ -247,6 +240,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Net45x/Themes/Generic.xaml b/src/WPFDevelopers.Net45x/Themes/Generic.xaml
index 1a031dd1..f1b35397 100644
--- a/src/WPFDevelopers.Net45x/Themes/Generic.xaml
+++ b/src/WPFDevelopers.Net45x/Themes/Generic.xaml
@@ -19,7 +19,6 @@
-
@@ -32,11 +31,6 @@
-
-
-
-
+ Margin="0,0,-1,0"
+ HorizontalAlignment="Stretch"
+ Background="{TemplateBinding TitleBackground}" />
+
@@ -106,7 +102,7 @@
-
@@ -699,18 +698,14 @@
-
-
-
-
+
+
@@ -729,12 +724,12 @@
-
+
-
+
@@ -746,7 +741,7 @@
-
+
@@ -762,12 +757,12 @@
-
+
-
+
@@ -1408,16 +1403,16 @@
-
+
-
+
-
+
-
+
@@ -1498,6 +1493,7 @@
@@ -3863,10 +3863,6 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Net45x/Window.cs b/src/WPFDevelopers.Net45x/Window.cs
index 706d3ae2..c007ca95 100644
--- a/src/WPFDevelopers.Net45x/Window.cs
+++ b/src/WPFDevelopers.Net45x/Window.cs
@@ -1,5 +1,7 @@
using System;
using System.Windows;
+using System.Windows.Automation.Peers;
+using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
@@ -7,16 +9,29 @@
using WPFDevelopers.Controls;
using WPFDevelopers.Core.Helpers;
using WPFDevelopers.Helpers;
-using static WPFDevelopers.Core.Helpers.MonitorHelper;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
namespace WPFDevelopers.Net45x
{
[TemplatePart(Name = TitleBarIcon, Type = typeof(Button))]
+ [TemplatePart(Name = HighTitleMaximizeButton, Type = typeof(Button))]
+ [TemplatePart(Name = HighTitleRestoreButton, Type = typeof(Button))]
+ [TemplatePart(Name = TitleBarMaximizeButton, Type = typeof(Button))]
+ [TemplatePart(Name = TitleBarRestoreButton, Type = typeof(Button))]
public class Window : System.Windows.Window
{
private const string TitleBarIcon = "PART_TitleBarIcon";
+ private const string HighTitleMaximizeButton = "PART_MaximizeButton";
+ private const string HighTitleRestoreButton = "PART_RestoreButton";
+ private const string TitleBarMaximizeButton = "PART_TitleBarMaximizeButton";
+ private const string TitleBarRestoreButton = "PART_TitleBarRestoreButton";
private WindowStyle _windowStyle;
private Button _titleBarIcon;
+ private Button _highTitleMaximizeButton;
+ private Button _highTitleRestoreButton;
+ private Button _titleBarMaximizeButton;
+ private Button _titleBarRestoreButton;
+ private IntPtr hWnd;
public static readonly DependencyProperty TitleHeightProperty =
DependencyProperty.Register("TitleHeight", typeof(double), typeof(Window), new PropertyMetadata(50d));
@@ -41,7 +56,6 @@ static Window()
public Window()
{
- Loaded += Window_Loaded;
WPFDevelopers.Resources.ThemeChanged += Resources_ThemeChanged;
CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow,
@@ -69,6 +83,10 @@ public override void OnApplyTemplate()
_titleBarIcon.MouseDoubleClick -= Icon_MouseDoubleClick;
_titleBarIcon.MouseDoubleClick += Icon_MouseDoubleClick;
}
+ _highTitleMaximizeButton = GetTemplateChild(HighTitleMaximizeButton) as Button;
+ _highTitleRestoreButton = GetTemplateChild(HighTitleRestoreButton) as Button;
+ _titleBarMaximizeButton = GetTemplateChild(TitleBarMaximizeButton) as Button;
+ _titleBarRestoreButton = GetTemplateChild(TitleBarRestoreButton) as Button;
}
private void Icon_MouseDoubleClick(object sender, MouseButtonEventArgs e)
@@ -114,13 +132,13 @@ private static T GetResourceKey(string key)
return resource;
return default;
}
-
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ protected override void OnSourceInitialized(EventArgs e)
{
+ base.OnSourceInitialized(e);
hWnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hWnd).AddHook(WindowProc);
if (TitleBarMode == TitleBarMode.Normal)
- TitleHeight = SystemParameters.WindowNonClientFrameThickness.Top + SystemParameters.WindowResizeBorderThickness.Top; //32;//SystemParameters.WindowNonClientFrameThickness.Top;
+ TitleHeight = SystemParameters.WindowNonClientFrameThickness.Top + SystemParameters.WindowResizeBorderThickness.Top;
}
protected override void OnContentRendered(EventArgs e)
@@ -159,7 +177,7 @@ private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
{
- MonitorHelper.SendMessage(hWnd, MonitorHelper.WindowsMessageCodes.WM_SYSCOMMAND, new IntPtr(MonitorHelper.WindowsMessageCodes.SC_MINIMIZE), IntPtr.Zero);
+ Win32.SendMessage(hWnd, WindowsMessageCodes.WM_SYSCOMMAND, new IntPtr(WindowsMessageCodes.SC_MINIMIZE), IntPtr.Zero);
}
private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
@@ -167,9 +185,6 @@ private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
SystemCommands.RestoreWindow(this);
}
-
- private IntPtr hWnd;
-
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
@@ -192,9 +207,81 @@ private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, re
handled = true;
}
break;
+ #region SnapLayouts
+ case WindowsMessageCodes.WM_NCHITTEST:
+ try
+ {
+ if (OSVersionHelper.IsSnapLayoutSupported() && ResizeMode != ResizeMode.NoResize && ResizeMode != ResizeMode.CanMinimize)
+ {
+ int x = lParam.ToInt32() & 0xffff;
+ int y = lParam.ToInt32() >> 16;
+ var dpiX = OSVersionHelper.DeviceUnitsScalingFactorX;
+ var button = TitleBarMode == TitleBarMode.Normal
+ ? (WindowState != WindowState.Maximized ? _titleBarMaximizeButton : _titleBarRestoreButton)
+ : (WindowState != WindowState.Maximized ? _highTitleMaximizeButton : _highTitleRestoreButton);
+ if (button != null)
+ {
+ var contentPresenter = button.Template.FindName("PART_ContentPresenter", button) as ContentPresenter;
+ if (contentPresenter != null)
+ {
+ var rect = new Rect(button.PointToScreen(new Point()),new Size(button.ActualWidth * dpiX, button.ActualHeight * dpiX));
+ if (rect.Contains(new Point(x, y)))
+ {
+ handled = true;
+ contentPresenter.Opacity = 1;
+ }
+ else
+ {
+ contentPresenter.Opacity = 0.7;
+ }
+ return new IntPtr(OSVersionHelper.HTMAXBUTTON);
+ }
+
+ }
+ }
+ }
+ catch (OverflowException)
+ {
+ handled = true;
+ }
+ break;
+ case WindowsMessageCodes.WM_NCLBUTTONDOWN:
+ if (OSVersionHelper.IsSnapLayoutSupported()
+ &&
+ (ResizeMode != ResizeMode.NoResize
+ ||
+ ResizeMode != ResizeMode.CanMinimize))
+ {
+ int x = lParam.ToInt32() & 0xffff;
+ int y = lParam.ToInt32() >> 16;
+ var dpiX = OSVersionHelper.DeviceUnitsScalingFactorX;
+ Button button = TitleBarMode == TitleBarMode.Normal
+ ? (WindowState != WindowState.Maximized ? _titleBarMaximizeButton : _titleBarRestoreButton)
+ : (WindowState != WindowState.Maximized ? _highTitleMaximizeButton : _highTitleRestoreButton);
+ if (button != null)
+ {
+ var rect = new Rect(button.PointToScreen(
+ new Point()),
+ new Size(button.ActualWidth * dpiX, button.ActualHeight * dpiX));
+ if (rect.Contains(new Point(x, y)))
+ {
+ handled = true;
+ IInvokeProvider invokeProv = new ButtonAutomationPeer(button).GetPattern(PatternInterface.Invoke) as IInvokeProvider;
+ invokeProv?.Invoke();
+ }
+ }
+ }
+ break;
+ #endregion
+ default:
+ handled = false;
+ break;
}
return IntPtr.Zero;
}
+
+
+
private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
{
var element = e.OriginalSource as FrameworkElement;
@@ -210,5 +297,5 @@ private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
#endregion
}
-
+
}
\ No newline at end of file
diff --git a/src/WPFDevelopers.Samples.Shared/Controls/BubblleControl/BubbleControl.cs b/src/WPFDevelopers.Samples.Shared/Controls/BubblleControl/BubblleControl.cs
similarity index 100%
rename from src/WPFDevelopers.Samples.Shared/Controls/BubblleControl/BubbleControl.cs
rename to src/WPFDevelopers.Samples.Shared/Controls/BubblleControl/BubblleControl.cs
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml
new file mode 100644
index 00000000..f071a7f2
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml.cs
new file mode 100644
index 00000000..8a0e42e6
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/AnimationGridExample.xaml.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using WPFDevelopers.Samples.Helpers;
+
+namespace WPFDevelopers.Samples.ExampleViews
+{
+ ///
+ /// AnimationGridExample.xaml 的交互逻辑
+ ///
+ public partial class AnimationGridExample : UserControl
+ {
+ public ObservableCollection GridItems
+ {
+ get { return (ObservableCollection)GetValue(GridItemsProperty); }
+ set { SetValue(GridItemsProperty, value); }
+ }
+
+ public static readonly DependencyProperty GridItemsProperty =
+ DependencyProperty.Register("GridItems", typeof(ObservableCollection), typeof(AnimationGridExample), new PropertyMetadata(null));
+ public AnimationGridExample()
+ {
+ InitializeComponent();
+ Loaded += OnAnimatedGridExample_Loaded;
+ }
+
+ private void OnAnimatedGridExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ var list = new List();
+ list.Add(new GridItem { Content = "Single", Data = "M0.5,0.5 L60.5,0.5 L60.5,43.26 L0.5,43.26 z", IsSelected = true });
+ list.Add(new GridItem { Content = "Dual", Data = "M0,0 L61,0 L61,43.760002 L0,43.760002 z M25.5,0 L35.5,0 L35.5,43.760002 L25.5,43.760002 z" });
+ list.Add(new GridItem { Content = "Three", Data = "M0,0 L61,0 L61,43.760002 L0,43.760002 z M17,0.5 L22,0.5 L22,43.260002 L17,43.260002 z M39,0.5 L44,0.5 L44,43.260002 L39,43.260002 z" });
+ GridItems = new ObservableCollection(list);
+ }
+
+ public ICommand IsSelectedCommand => new RelayCommand(param =>
+ {
+ if (param == null) return;
+ var item = (GridItem)param;
+ if (item == null) return;
+ MyPanel.ShowItem(item);
+ });
+
+ }
+ public class GridItem : ViewModelBase
+ {
+ public string Content { get; set; }
+ public string Data { get; set; }
+
+ private bool _isSelected;
+ public bool IsSelected
+ {
+ get => _isSelected;
+ set { _isSelected = value; NotifyPropertyChange("IsSelected"); }
+ }
+ }
+}
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml
index 2aa7ff12..fb608303 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml
@@ -561,6 +561,18 @@
Binding="{Binding Address}"
Header="Address"
IsReadOnly="True" />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml.cs
index d8e2b57c..6814fe90 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml.cs
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/BasicControlsExample.xaml.cs
@@ -31,6 +31,7 @@ public partial class BasicControlsExample : UserControl
DependencyProperty.Register("AllSelected", typeof(bool), typeof(BasicControlsExample),
new PropertyMetadata(AllSelectedChangedCallback));
+ public static List ContactMethods { get; } = new List { "Tel", "Fax", "MB" };
public BasicControlsExample()
{
InitializeComponent();
@@ -54,6 +55,7 @@ private void MainView_Loaded(object sender, RoutedEventArgs e)
Date = time,
Name = "WPFDevelopers",
Address = "One Microsoft Way, Redmond",
+ ContactMethod = "MB",
Children = new List
{
new UserModel { Name = "WPFDevelopers1.1",Children=new List
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/BubblleControlExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/BubblleControlExample.xaml
index 62c0bd91..c5e229da 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/BubblleControlExample.xaml
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/BubblleControlExample.xaml
@@ -100,15 +100,15 @@
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/DateRangePickerExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/DateRangePickerExample.xaml
index 1b84089a..3d83c0a5 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/DateRangePickerExample.xaml
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/DateRangePickerExample.xaml
@@ -33,6 +33,8 @@
wd:ElementHelper.IsClear="True"
EndDate="{Binding EndDate, RelativeSource={RelativeSource AncestorType=local:DateRangePickerExample}}"
EndWatermark="结束日期"
+ MaxDate="2025-08-30"
+ MinDate="2025-08-06"
StartDate="{Binding StartDate, RelativeSource={RelativeSource AncestorType=local:DateRangePickerExample}}"
StartWatermark="开始日期" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/GestureUnlockExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/GestureUnlockExample.xaml.cs
new file mode 100644
index 00000000..b88ce27c
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/GestureUnlockExample.xaml.cs
@@ -0,0 +1,69 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using WPFDevelopers.Controls;
+using WPFDevelopers.Samples.Helpers;
+
+namespace WPFDevelopers.Sample.ExampleViews
+{
+ ///
+ /// GestureUnlockExample.xaml 的交互逻辑
+ ///
+ public partial class GestureUnlockExample : UserControl
+ {
+ private string _password = "0426";
+ private enum GestureUnlockType
+ {
+ Unlock1,
+ Unlock2
+ }
+ public GestureUnlockExample()
+ {
+ InitializeComponent();
+ }
+
+ private void HandleGestureUnlock(string pwd, GestureUnlockType unlockType)
+ {
+ if (pwd.Length < 4)
+ {
+ SetGestureState(unlockType, GestureState.Error);
+ Message.PushDesktop("手势错误,最少 4 个节点!", MessageBoxImage.Error, true);
+ return;
+ }
+
+ if (pwd != _password)
+ {
+ SetGestureState(unlockType, GestureState.Error);
+ Message.PushDesktop("手势错误,请重新解锁!", MessageBoxImage.Error, true);
+ return;
+ }
+
+ SetGestureState(unlockType, GestureState.Success);
+ Message.Push("手势正确!", MessageBoxImage.Information, true);
+ }
+
+ private void SetGestureState(GestureUnlockType unlockType, GestureState state)
+ {
+ if (unlockType == GestureUnlockType.Unlock1)
+ {
+ myGestureUnlock.State = state;
+ }
+ else if (unlockType == GestureUnlockType.Unlock2)
+ {
+ myGestureUnlock2.State = state;
+ }
+ }
+
+ private void GestureCompleted(object sender, RoutedEventArgs e)
+ {
+ var pwd = e.OriginalSource.ToString();
+ HandleGestureUnlock(pwd, GestureUnlockType.Unlock1);
+ }
+
+ public ICommand GestureCompletedCommand => new RelayCommand(param =>
+ {
+ var pwd = param.ToString();
+ HandleGestureUnlock(pwd, GestureUnlockType.Unlock2);
+ });
+ }
+}
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml
new file mode 100644
index 00000000..ded17743
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml.cs
new file mode 100644
index 00000000..856324a6
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailExample.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace WPFDevelopers.Sample.ExampleViews
+{
+ ///
+ /// IconicThumbnailExample.xaml 的交互逻辑
+ ///
+ public partial class IconicThumbnailExample: UserControl
+ {
+ public IconicThumbnailExample()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml
new file mode 100644
index 00000000..266a9f25
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml.cs
new file mode 100644
index 00000000..396d851f
--- /dev/null
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/IconicThumbnailWindowExample.xaml.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using WPFDevelopers.Helpers;
+
+namespace WPFDevelopers.Sample.ExampleViews
+{
+ ///
+ /// IconicThumbnailWindowExample.xaml 的交互逻辑
+ ///
+ public partial class IconicThumbnailWindowExample
+ {
+ private List fileList = new List();
+ private int currentFileIndex = -1;
+ public IconicThumbnailWindowExample()
+ {
+ InitializeComponent();
+ Loaded += IconicThumbnailWindowExample_Loaded;
+ }
+
+ private void IconicThumbnailWindowExample_Loaded(object sender, RoutedEventArgs e)
+ {
+ fileList.Clear();
+ currentFileIndex = -1;
+ var directorys = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "IconicThumbnail");
+ if (!Directory.Exists(directorys)) return;
+ string[] files = Directory.GetFiles(directorys);
+ fileList.AddRange(files);
+ }
+
+ private void BtnPrevious_Click(object sender, RoutedEventArgs e)
+ {
+ if (fileList.Count == 0) return;
+ currentFileIndex = (currentFileIndex + 1) % fileList.Count;
+ var img = fileList[currentFileIndex];
+ ImagePreview.Source = new BitmapImage(new Uri(img));
+ this.SetIconicThumbnail(img);
+ }
+ private void BtnNext_Click(object sender, RoutedEventArgs e)
+ {
+ if (fileList.Count == 0) return;
+ currentFileIndex = (currentFileIndex - 1 + fileList.Count) % fileList.Count;
+ var img = fileList[currentFileIndex];
+ ImagePreview.Source = new BitmapImage(new Uri(img));
+ this.SetIconicThumbnail(img);
+ }
+ }
+}
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/CustomControl/InputBoxBase.cs b/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/CustomControl/InputBoxBase.cs
index 126f6446..00c9e120 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/CustomControl/InputBoxBase.cs
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/CustomControl/InputBoxBase.cs
@@ -73,7 +73,7 @@ private static void OnIconChanged(DependencyObject sender, DependencyPropertyCha
{
try
{
- control.ApplyIcon(new BitmapImage(new Uri("pack://application:,,,/ExampleViews/LoginWindow/" + control.Icon)));
+ control.ApplyIcon(new BitmapImage(new Uri("pack://application:,,,/WPFDevelopers.Samples;component/Resources/Assets/" + control.Icon)));
}
catch (Exception ex)
{
diff --git a/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/Generic.xaml b/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/Generic.xaml
index dd97f639..e93d6a19 100644
--- a/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/Generic.xaml
+++ b/src/WPFDevelopers.Samples.Shared/ExampleViews/LoginWindow/Generic.xaml
@@ -61,12 +61,6 @@
-
-
\ No newline at end of file
diff --git a/src/WPFDevelopers.Shared/Styles/Styles.Slider.xaml b/src/WPFDevelopers.Shared/Styles/Styles.Slider.xaml
index 1b2fa4c3..70be753f 100644
--- a/src/WPFDevelopers.Shared/Styles/Styles.Slider.xaml
+++ b/src/WPFDevelopers.Shared/Styles/Styles.Slider.xaml
@@ -87,16 +87,16 @@
Background="{TemplateBinding Background}" />
-
+
-
+
-
+
-
+
@@ -249,6 +249,7 @@
BasedOn="{StaticResource WD.ControlBasicStyle}"
TargetType="{x:Type Slider}">
+
diff --git a/src/WPFDevelopers.Shared/Themes/DateRangePicker.xaml b/src/WPFDevelopers.Shared/Themes/DateRangePicker.xaml
index 26823ad7..0bd4507c 100644
--- a/src/WPFDevelopers.Shared/Themes/DateRangePicker.xaml
+++ b/src/WPFDevelopers.Shared/Themes/DateRangePicker.xaml
@@ -141,7 +141,10 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/src/WPFDevelopers.Shared/Themes/MultiSelectComboBox.xaml b/src/WPFDevelopers.Shared/Themes/MultiSelectComboBox.xaml
index f4a5f19d..3708bc9b 100644
--- a/src/WPFDevelopers.Shared/Themes/MultiSelectComboBox.xaml
+++ b/src/WPFDevelopers.Shared/Themes/MultiSelectComboBox.xaml
@@ -158,7 +158,8 @@
Focusable="True"
IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Placement="Bottom"
- PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}">
+ PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
+ StaysOpen="False">
+ PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
+ StaysOpen="False">
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/src/WPFDevelopers.Shared/Themes/Theme40.txt b/src/WPFDevelopers.Shared/Themes/Theme40.txt
index da2461e1..75cabb63 100644
--- a/src/WPFDevelopers.Shared/Themes/Theme40.txt
+++ b/src/WPFDevelopers.Shared/Themes/Theme40.txt
@@ -33,7 +33,6 @@ Basic\ControlBasic.xaml
..\Styles\Styles.GridSplitter.xaml
..\Styles\Styles.Label.xaml
..\Styles\Styles.RepeatButton.xaml
-..\Styles\Styles.Grid.xaml
..\Microsoft.Expression.Controls\Themes\Generic.xaml
..\Microsoft.Expression.Drawing\Themes\Generic.xaml
@@ -70,4 +69,6 @@ TimePicker.xaml
Drawer.xaml
DateRangePicker.xaml
Tag.xaml
-NavScrollPanel.xaml
\ No newline at end of file
+NavScrollPanel.xaml
+GestureUnlock.xaml
+WDUserControl.xaml
diff --git a/src/WPFDevelopers.Shared/Themes/Theme45x.txt b/src/WPFDevelopers.Shared/Themes/Theme45x.txt
index e99fa592..59021114 100644
--- a/src/WPFDevelopers.Shared/Themes/Theme45x.txt
+++ b/src/WPFDevelopers.Shared/Themes/Theme45x.txt
@@ -33,7 +33,6 @@ Basic\ControlBasic.xaml
..\Styles\Styles.GridSplitter.xaml
..\Styles\Styles.Label.xaml
..\Styles\Styles.RepeatButton.xaml
-..\Styles\Styles.Grid.xaml
..\Microsoft.Expression.Controls\Themes\Generic.xaml
..\Microsoft.Expression.Drawing\Themes\Generic.xaml
@@ -71,4 +70,6 @@ TimePicker.xaml
Drawer.xaml
DateRangePicker.xaml
Tag.xaml
-NavScrollPanel.xaml
\ No newline at end of file
+NavScrollPanel.xaml
+GestureUnlock.xaml
+WDUserControl.xaml
\ No newline at end of file
diff --git a/src/WPFDevelopers.Shared/Themes/TimePicker.xaml b/src/WPFDevelopers.Shared/Themes/TimePicker.xaml
index e2de6dbb..62926d01 100644
--- a/src/WPFDevelopers.Shared/Themes/TimePicker.xaml
+++ b/src/WPFDevelopers.Shared/Themes/TimePicker.xaml
@@ -216,7 +216,8 @@
AllowsTransparency="True"
IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Placement="Bottom"
- PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}">
+ PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
+ StaysOpen="False">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/WPFDevelopers.Shared/WPFDevelopers.Shared.projitems b/src/WPFDevelopers.Shared/WPFDevelopers.Shared.projitems
index d4fbf8fe..1a2cfd38 100644
--- a/src/WPFDevelopers.Shared/WPFDevelopers.Shared.projitems
+++ b/src/WPFDevelopers.Shared/WPFDevelopers.Shared.projitems
@@ -9,9 +9,11 @@
WPFDevelopers
+
+
@@ -23,6 +25,8 @@
+
+
@@ -59,6 +63,7 @@
+
@@ -69,7 +74,6 @@
-
@@ -146,7 +150,7 @@
-
+
@@ -321,10 +325,6 @@
MSBuild:Compile
Designer
-
- MSBuild:Compile
- Designer
-
MSBuild:Compile
Designer
@@ -545,6 +545,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
@@ -557,6 +561,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+