chore: use file-scoped namespace

This commit is contained in:
NaBian committed 2022-03-13 20:28:58 +08:00
1 parent 99d2fafb72
commit bbf1b7d4c6
748 files changed
+57929 -58678

No files matched your search

@@ -8,164 +8,163 @@ using HandyControl.Data;
using HandyControl.Expression.Drawing;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class AnimationPath : Shape
{
public class AnimationPath : Shape
private Storyboard _storyboard;
private double _pathLength;
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(nameof(Data),
typeof(Geometry), typeof(AnimationPath), new FrameworkPropertyMetadata(null,
OnPropertiesChanged));
private static void OnPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
private Storyboard _storyboard;
private double _pathLength;
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(nameof(Data),
typeof(Geometry), typeof(AnimationPath), new FrameworkPropertyMetadata(null,
OnPropertiesChanged));
private static void OnPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
if (d is AnimationPath path)
{
if (d is AnimationPath path)
{
path.UpdatePath();
}
path.UpdatePath();
}
public Geometry Data
{
get => (Geometry) GetValue(DataProperty);
set => SetValue(DataProperty, value);
}
protected override Geometry DefiningGeometry => Data ?? Geometry.Empty;
public static readonly DependencyProperty PathLengthProperty = DependencyProperty.Register(
"PathLength", typeof(double), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnPropertiesChanged));
public double PathLength
{
get => (double) GetValue(PathLengthProperty);
set => SetValue(PathLengthProperty, value);
}
public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
"Duration", typeof(Duration), typeof(AnimationPath), new FrameworkPropertyMetadata(new Duration(TimeSpan.FromSeconds(2)),
OnPropertiesChanged));
public Duration Duration
{
get => (Duration) GetValue(DurationProperty);
set => SetValue(DurationProperty, value);
}
public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register(
"IsPlaying", typeof(bool), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, (o, args) =>
{
var ctl = (AnimationPath) o;
var v = (bool) args.NewValue;
if (v)
{
ctl.UpdatePath();
}
else
{
ctl._storyboard?.Pause();
}
}));
public bool IsPlaying
{
get => (bool) GetValue(IsPlayingProperty);
set => SetValue(IsPlayingProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty RepeatBehaviorProperty =
Timeline.RepeatBehaviorProperty.AddOwner(typeof(AnimationPath),
new PropertyMetadata(RepeatBehavior.Forever));
public RepeatBehavior RepeatBehavior
{
get => (RepeatBehavior) GetValue(RepeatBehaviorProperty);
set => SetValue(RepeatBehaviorProperty, value);
}
public static readonly DependencyProperty FillBehaviorProperty =
Timeline.FillBehaviorProperty.AddOwner(typeof(AnimationPath), new PropertyMetadata(FillBehavior.Stop));
public FillBehavior FillBehavior
{
get { return (FillBehavior) GetValue(FillBehaviorProperty); }
set { SetValue(FillBehaviorProperty, value); }
}
static AnimationPath()
{
StretchProperty.AddOwner(typeof(AnimationPath), new FrameworkPropertyMetadata(Stretch.Uniform,
OnPropertiesChanged));
StrokeThicknessProperty.AddOwner(typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double1Box,
OnPropertiesChanged));
}
public AnimationPath() => Loaded += (s, e) => UpdatePath();
public static readonly RoutedEvent CompletedEvent =
EventManager.RegisterRoutedEvent("Completed", RoutingStrategy.Bubble,
typeof(EventHandler), typeof(AnimationPath));
public event EventHandler Completed
{
add => AddHandler(CompletedEvent, value);
remove => RemoveHandler(CompletedEvent, value);
}
private void UpdatePath()
{
if (!Duration.HasTimeSpan || !IsPlaying) return;
_pathLength = PathLength > 0 ? PathLength : Data.GetTotalLength(new Size(ActualWidth, ActualHeight), StrokeThickness);
if (MathHelper.IsVerySmall(_pathLength)) return;
StrokeDashOffset = _pathLength;
StrokeDashArray = new DoubleCollection(new List<double>
{
_pathLength,
_pathLength
});
if (_storyboard != null)
{
_storyboard.Stop();
_storyboard.Completed -= Storyboard_Completed;
}
_storyboard = new Storyboard
{
RepeatBehavior = RepeatBehavior,
FillBehavior = FillBehavior
};
_storyboard.Completed += Storyboard_Completed;
var frames = new DoubleAnimationUsingKeyFrames();
var frameIn = new LinearDoubleKeyFrame
{
Value = _pathLength,
KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero)
};
frames.KeyFrames.Add(frameIn);
var frameOut = new LinearDoubleKeyFrame
{
Value = FillBehavior == FillBehavior.Stop ? -_pathLength : 0,
KeyTime = KeyTime.FromTimeSpan(Duration.TimeSpan)
};
frames.KeyFrames.Add(frameOut);
Storyboard.SetTarget(frames, this);
Storyboard.SetTargetProperty(frames, new PropertyPath(StrokeDashOffsetProperty));
_storyboard.Children.Add(frames);
_storyboard.Begin();
}
private void Storyboard_Completed(object sender, EventArgs e) => RaiseEvent(new RoutedEventArgs(CompletedEvent));
}
}
public Geometry Data
{
get => (Geometry) GetValue(DataProperty);
set => SetValue(DataProperty, value);
}
protected override Geometry DefiningGeometry => Data ?? Geometry.Empty;
public static readonly DependencyProperty PathLengthProperty = DependencyProperty.Register(
"PathLength", typeof(double), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnPropertiesChanged));
public double PathLength
{
get => (double) GetValue(PathLengthProperty);
set => SetValue(PathLengthProperty, value);
}
public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
"Duration", typeof(Duration), typeof(AnimationPath), new FrameworkPropertyMetadata(new Duration(TimeSpan.FromSeconds(2)),
OnPropertiesChanged));
public Duration Duration
{
get => (Duration) GetValue(DurationProperty);
set => SetValue(DurationProperty, value);
}
public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register(
"IsPlaying", typeof(bool), typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, (o, args) =>
{
var ctl = (AnimationPath) o;
var v = (bool) args.NewValue;
if (v)
{
ctl.UpdatePath();
}
else
{
ctl._storyboard?.Pause();
}
}));
public bool IsPlaying
{
get => (bool) GetValue(IsPlayingProperty);
set => SetValue(IsPlayingProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty RepeatBehaviorProperty =
Timeline.RepeatBehaviorProperty.AddOwner(typeof(AnimationPath),
new PropertyMetadata(RepeatBehavior.Forever));
public RepeatBehavior RepeatBehavior
{
get => (RepeatBehavior) GetValue(RepeatBehaviorProperty);
set => SetValue(RepeatBehaviorProperty, value);
}
public static readonly DependencyProperty FillBehaviorProperty =
Timeline.FillBehaviorProperty.AddOwner(typeof(AnimationPath), new PropertyMetadata(FillBehavior.Stop));
public FillBehavior FillBehavior
{
get { return (FillBehavior) GetValue(FillBehaviorProperty); }
set { SetValue(FillBehaviorProperty, value); }
}
static AnimationPath()
{
StretchProperty.AddOwner(typeof(AnimationPath), new FrameworkPropertyMetadata(Stretch.Uniform,
OnPropertiesChanged));
StrokeThicknessProperty.AddOwner(typeof(AnimationPath), new FrameworkPropertyMetadata(ValueBoxes.Double1Box,
OnPropertiesChanged));
}
public AnimationPath() => Loaded += (s, e) => UpdatePath();
public static readonly RoutedEvent CompletedEvent =
EventManager.RegisterRoutedEvent("Completed", RoutingStrategy.Bubble,
typeof(EventHandler), typeof(AnimationPath));
public event EventHandler Completed
{
add => AddHandler(CompletedEvent, value);
remove => RemoveHandler(CompletedEvent, value);
}
private void UpdatePath()
{
if (!Duration.HasTimeSpan || !IsPlaying) return;
_pathLength = PathLength > 0 ? PathLength : Data.GetTotalLength(new Size(ActualWidth, ActualHeight), StrokeThickness);
if (MathHelper.IsVerySmall(_pathLength)) return;
StrokeDashOffset = _pathLength;
StrokeDashArray = new DoubleCollection(new List<double>
{
_pathLength,
_pathLength
});
if (_storyboard != null)
{
_storyboard.Stop();
_storyboard.Completed -= Storyboard_Completed;
}
_storyboard = new Storyboard
{
RepeatBehavior = RepeatBehavior,
FillBehavior = FillBehavior
};
_storyboard.Completed += Storyboard_Completed;
var frames = new DoubleAnimationUsingKeyFrames();
var frameIn = new LinearDoubleKeyFrame
{
Value = _pathLength,
KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero)
};
frames.KeyFrames.Add(frameIn);
var frameOut = new LinearDoubleKeyFrame
{
Value = FillBehavior == FillBehavior.Stop ? -_pathLength : 0,
KeyTime = KeyTime.FromTimeSpan(Duration.TimeSpan)
};
frames.KeyFrames.Add(frameOut);
Storyboard.SetTarget(frames, this);
Storyboard.SetTargetProperty(frames, new PropertyPath(StrokeDashOffsetProperty));
_storyboard.Children.Add(frames);
_storyboard.Begin();
}
private void Storyboard_Completed(object sender, EventArgs e) => RaiseEvent(new RoutedEventArgs(CompletedEvent));
}
@@ -4,98 +4,97 @@ using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
namespace HandyControl.Controls;
/// <summary>
/// 标记
/// </summary>
public class Badge : ContentControl
{
/// <summary>
/// 标记
/// </summary>
public class Badge : ContentControl
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble,
typeof(EventHandler<FunctionEventArgs<int>>), typeof(Badge));
public event EventHandler<FunctionEventArgs<int>> ValueChanged
{
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble,
typeof(EventHandler<FunctionEventArgs<int>>), typeof(Badge));
public event EventHandler<FunctionEventArgs<int>> ValueChanged
{
add => AddHandler(ValueChangedEvent, value);
remove => RemoveHandler(ValueChangedEvent, value);
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(Badge), new PropertyMetadata("0"));
public string Text
{
get => (string) GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(int), typeof(Badge), new PropertyMetadata(ValueBoxes.Int0Box, OnValueChanged));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Badge) d;
var v = (int) e.NewValue;
ctl.SetCurrentValue(TextProperty, v <= ctl.Maximum ? v.ToString() : $"{ctl.Maximum}+");
if (ctl.IsInitialized)
{
ctl.RaiseEvent(new FunctionEventArgs<int>(ValueChangedEvent, ctl)
{
Info = v
});
}
}
public int Value
{
get => (int) GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
"Status", typeof(BadgeStatus), typeof(Badge), new PropertyMetadata(default(BadgeStatus)));
public BadgeStatus Status
{
get => (BadgeStatus) GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
}
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
"Maximum", typeof(int), typeof(Badge), new PropertyMetadata(ValueBoxes.Int99Box, OnMaximumChanged));
private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Badge) d;
var v = ctl.Value;
ctl.SetCurrentValue(TextProperty, v <= ctl.Maximum ? v.ToString() : $"{ctl.Maximum}+");
}
public int Maximum
{
get => (int) GetValue(MaximumProperty);
set => SetValue(MaximumProperty, value);
}
public static readonly DependencyProperty BadgeMarginProperty = DependencyProperty.Register(
"BadgeMargin", typeof(Thickness), typeof(Badge), new PropertyMetadata(default(Thickness)));
public Thickness BadgeMargin
{
get => (Thickness) GetValue(BadgeMarginProperty);
set => SetValue(BadgeMarginProperty, value);
}
public static readonly DependencyProperty ShowBadgeProperty = DependencyProperty.Register(
"ShowBadge", typeof(bool), typeof(Badge), new PropertyMetadata(ValueBoxes.TrueBox));
public bool ShowBadge
{
get => (bool) GetValue(ShowBadgeProperty);
set => SetValue(ShowBadgeProperty, ValueBoxes.BooleanBox(value));
}
protected override Geometry GetLayoutClip(Size layoutSlotSize) => null;
add => AddHandler(ValueChangedEvent, value);
remove => RemoveHandler(ValueChangedEvent, value);
}
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(Badge), new PropertyMetadata("0"));
public string Text
{
get => (string) GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(int), typeof(Badge), new PropertyMetadata(ValueBoxes.Int0Box, OnValueChanged));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Badge) d;
var v = (int) e.NewValue;
ctl.SetCurrentValue(TextProperty, v <= ctl.Maximum ? v.ToString() : $"{ctl.Maximum}+");
if (ctl.IsInitialized)
{
ctl.RaiseEvent(new FunctionEventArgs<int>(ValueChangedEvent, ctl)
{
Info = v
});
}
}
public int Value
{
get => (int) GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
"Status", typeof(BadgeStatus), typeof(Badge), new PropertyMetadata(default(BadgeStatus)));
public BadgeStatus Status
{
get => (BadgeStatus) GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
}
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
"Maximum", typeof(int), typeof(Badge), new PropertyMetadata(ValueBoxes.Int99Box, OnMaximumChanged));
private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Badge) d;
var v = ctl.Value;
ctl.SetCurrentValue(TextProperty, v <= ctl.Maximum ? v.ToString() : $"{ctl.Maximum}+");
}
public int Maximum
{
get => (int) GetValue(MaximumProperty);
set => SetValue(MaximumProperty, value);
}
public static readonly DependencyProperty BadgeMarginProperty = DependencyProperty.Register(
"BadgeMargin", typeof(Thickness), typeof(Badge), new PropertyMetadata(default(Thickness)));
public Thickness BadgeMargin
{
get => (Thickness) GetValue(BadgeMarginProperty);
set => SetValue(BadgeMarginProperty, value);
}
public static readonly DependencyProperty ShowBadgeProperty = DependencyProperty.Register(
"ShowBadge", typeof(bool), typeof(Badge), new PropertyMetadata(ValueBoxes.TrueBox));
public bool ShowBadge
{
get => (bool) GetValue(ShowBadgeProperty);
set => SetValue(ShowBadgeProperty, ValueBoxes.BooleanBox(value));
}
protected override Geometry GetLayoutClip(Size layoutSlotSize) => null;
}
@@ -7,110 +7,109 @@ using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media.Effects;
namespace HandyControl.Controls
namespace HandyControl.Controls;
[DefaultProperty("Content")]
[ContentProperty("Content")]
public class BlendEffectBox : Control
{
[DefaultProperty("Content")]
[ContentProperty("Content")]
public class BlendEffectBox : Control
private readonly ContentPresenter _effectBottomPresenter;
private readonly ContentPresenter _effectTopPresenter;
private bool _isInternalAction;
public BlendEffectBox()
{
private readonly ContentPresenter _effectBottomPresenter;
_effectTopPresenter = new ContentPresenter();
ActualContent = _effectTopPresenter;
private readonly ContentPresenter _effectTopPresenter;
private bool _isInternalAction;
public BlendEffectBox()
_effectBottomPresenter = new ContentPresenter();
_effectBottomPresenter.SetBinding(ContentPresenter.ContentProperty, new Binding(ContentProperty.Name)
{
_effectTopPresenter = new ContentPresenter();
ActualContent = _effectTopPresenter;
Source = this
});
_effectBottomPresenter = new ContentPresenter();
_effectBottomPresenter.SetBinding(ContentPresenter.ContentProperty, new Binding(ContentProperty.Name)
{
Source = this
});
var effects = new ObservableCollection<Effect>();
effects.CollectionChanged += OnEffectsChanged;
Effects = effects;
}
var effects = new ObservableCollection<Effect>();
effects.CollectionChanged += OnEffectsChanged;
Effects = effects;
private void OnEffectsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (Effects == null || Effects.Count == 0)
{
ClearEffect(_effectTopPresenter);
return;
}
private void OnEffectsChanged(object sender, NotifyCollectionChangedEventArgs e)
if (_isInternalAction) return;
_isInternalAction = true;
AddEffect(_effectTopPresenter, Effects.Count);
_isInternalAction = false;
}
private void ClearEffect(ContentPresenter presenter)
{
if (presenter == null) return;
if (ReferenceEquals(_effectBottomPresenter, presenter))
{
if (Effects == null || Effects.Count == 0)
_effectBottomPresenter.SetCurrentValue(EffectProperty, null);
return;
}
presenter.SetCurrentValue(EffectProperty, null);
ClearEffect(presenter.Content as ContentPresenter);
}
private void AddEffect(ContentPresenter presenter, int count)
{
var newCount = --count;
if (newCount >= 0)
{
presenter.Effect = Effects[newCount];
var nextCount = --count;
if (nextCount >= 1)
{
ClearEffect(_effectTopPresenter);
return;
var content = new ContentPresenter();
presenter.Content = content;
AddEffect(content, newCount);
}
if (_isInternalAction) return;
_isInternalAction = true;
AddEffect(_effectTopPresenter, Effects.Count);
_isInternalAction = false;
}
private void ClearEffect(ContentPresenter presenter)
{
if (presenter == null) return;
if (ReferenceEquals(_effectBottomPresenter, presenter))
else if (nextCount >= 0)
{
_effectBottomPresenter.SetCurrentValue(EffectProperty, null);
return;
_effectBottomPresenter.Effect = Effects[0];
presenter.Content = _effectBottomPresenter;
}
presenter.SetCurrentValue(EffectProperty, null);
ClearEffect(presenter.Content as ContentPresenter);
}
private void AddEffect(ContentPresenter presenter, int count)
{
var newCount = --count;
if (newCount >= 0)
else
{
presenter.Effect = Effects[newCount];
var nextCount = --count;
if (nextCount >= 1)
{
var content = new ContentPresenter();
presenter.Content = content;
AddEffect(content, newCount);
}
else if (nextCount >= 0)
{
_effectBottomPresenter.Effect = Effects[0];
presenter.Content = _effectBottomPresenter;
}
else
{
presenter.Content = _effectBottomPresenter;
}
presenter.Content = _effectBottomPresenter;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Bindable(true)]
public Collection<Effect> Effects { get; }
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(FrameworkElement), typeof(BlendEffectBox), new PropertyMetadata(default(FrameworkElement)));
public FrameworkElement Content
{
get => (FrameworkElement) GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
internal static readonly DependencyProperty ActualContentProperty = DependencyProperty.Register(
"ActualContent", typeof(FrameworkElement), typeof(BlendEffectBox), new PropertyMetadata(default(FrameworkElement)));
internal FrameworkElement ActualContent
{
get => (FrameworkElement) GetValue(ActualContentProperty);
set => SetValue(ActualContentProperty, value);
}
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Bindable(true)]
public Collection<Effect> Effects { get; }
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(FrameworkElement), typeof(BlendEffectBox), new PropertyMetadata(default(FrameworkElement)));
public FrameworkElement Content
{
get => (FrameworkElement) GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
internal static readonly DependencyProperty ActualContentProperty = DependencyProperty.Register(
"ActualContent", typeof(FrameworkElement), typeof(BlendEffectBox), new PropertyMetadata(default(FrameworkElement)));
internal FrameworkElement ActualContent
{
get => (FrameworkElement) GetValue(ActualContentProperty);
set => SetValue(ActualContentProperty, value);
}
}
@@ -2,86 +2,85 @@
using System.Windows;
using System.Windows.Controls;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class Card : ContentControl
{
public class Card : ContentControl
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header", typeof(object), typeof(Card), new PropertyMetadata(default(object)));
public object Header
{
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header", typeof(object), typeof(Card), new PropertyMetadata(default(object)));
public object Header
{
get => GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
}
public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register(
"HeaderTemplate", typeof(DataTemplate), typeof(Card), new PropertyMetadata(default(DataTemplate)));
[Bindable(true), Category("Content")]
public DataTemplate HeaderTemplate
{
get => (DataTemplate) GetValue(HeaderTemplateProperty);
set => SetValue(HeaderTemplateProperty, value);
}
public static readonly DependencyProperty HeaderTemplateSelectorProperty = DependencyProperty.Register(
"HeaderTemplateSelector", typeof(DataTemplateSelector), typeof(Card), new PropertyMetadata(default(DataTemplateSelector)));
[Bindable(true), Category("Content")]
public DataTemplateSelector HeaderTemplateSelector
{
get => (DataTemplateSelector) GetValue(HeaderTemplateSelectorProperty);
set => SetValue(HeaderTemplateSelectorProperty, value);
}
public static readonly DependencyProperty HeaderStringFormatProperty = DependencyProperty.Register(
"HeaderStringFormat", typeof(string), typeof(Card), new PropertyMetadata(default(string)));
[Bindable(true), Category("Content")]
public string HeaderStringFormat
{
get => (string) GetValue(HeaderStringFormatProperty);
set => SetValue(HeaderStringFormatProperty, value);
}
public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(
"Footer", typeof(object), typeof(Card), new PropertyMetadata(default(object)));
public object Footer
{
get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);
}
public static readonly DependencyProperty FooterTemplateProperty = DependencyProperty.Register(
"FooterTemplate", typeof(DataTemplate), typeof(Card), new PropertyMetadata(default(DataTemplate)));
[Bindable(true), Category("Content")]
public DataTemplate FooterTemplate
{
get => (DataTemplate) GetValue(FooterTemplateProperty);
set => SetValue(FooterTemplateProperty, value);
}
public static readonly DependencyProperty FooterTemplateSelectorProperty = DependencyProperty.Register(
"FooterTemplateSelector", typeof(DataTemplateSelector), typeof(Card), new PropertyMetadata(default(DataTemplateSelector)));
[Bindable(true), Category("Content")]
public DataTemplateSelector FooterTemplateSelector
{
get => (DataTemplateSelector) GetValue(FooterTemplateSelectorProperty);
set => SetValue(FooterTemplateSelectorProperty, value);
}
public static readonly DependencyProperty FooterStringFormatProperty = DependencyProperty.Register(
"FooterStringFormat", typeof(string), typeof(Card), new PropertyMetadata(default(string)));
[Bindable(true), Category("Content")]
public string FooterStringFormat
{
get => (string) GetValue(FooterStringFormatProperty);
set => SetValue(FooterStringFormatProperty, value);
}
get => GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
}
}
public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register(
"HeaderTemplate", typeof(DataTemplate), typeof(Card), new PropertyMetadata(default(DataTemplate)));
[Bindable(true), Category("Content")]
public DataTemplate HeaderTemplate
{
get => (DataTemplate) GetValue(HeaderTemplateProperty);
set => SetValue(HeaderTemplateProperty, value);
}
public static readonly DependencyProperty HeaderTemplateSelectorProperty = DependencyProperty.Register(
"HeaderTemplateSelector", typeof(DataTemplateSelector), typeof(Card), new PropertyMetadata(default(DataTemplateSelector)));
[Bindable(true), Category("Content")]
public DataTemplateSelector HeaderTemplateSelector
{
get => (DataTemplateSelector) GetValue(HeaderTemplateSelectorProperty);
set => SetValue(HeaderTemplateSelectorProperty, value);
}
public static readonly DependencyProperty HeaderStringFormatProperty = DependencyProperty.Register(
"HeaderStringFormat", typeof(string), typeof(Card), new PropertyMetadata(default(string)));
[Bindable(true), Category("Content")]
public string HeaderStringFormat
{
get => (string) GetValue(HeaderStringFormatProperty);
set => SetValue(HeaderStringFormatProperty, value);
}
public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(
"Footer", typeof(object), typeof(Card), new PropertyMetadata(default(object)));
public object Footer
{
get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);
}
public static readonly DependencyProperty FooterTemplateProperty = DependencyProperty.Register(
"FooterTemplate", typeof(DataTemplate), typeof(Card), new PropertyMetadata(default(DataTemplate)));
[Bindable(true), Category("Content")]
public DataTemplate FooterTemplate
{
get => (DataTemplate) GetValue(FooterTemplateProperty);
set => SetValue(FooterTemplateProperty, value);
}
public static readonly DependencyProperty FooterTemplateSelectorProperty = DependencyProperty.Register(
"FooterTemplateSelector", typeof(DataTemplateSelector), typeof(Card), new PropertyMetadata(default(DataTemplateSelector)));
[Bindable(true), Category("Content")]
public DataTemplateSelector FooterTemplateSelector
{
get => (DataTemplateSelector) GetValue(FooterTemplateSelectorProperty);
set => SetValue(FooterTemplateSelectorProperty, value);
}
public static readonly DependencyProperty FooterStringFormatProperty = DependencyProperty.Register(
"FooterStringFormat", typeof(string), typeof(Card), new PropertyMetadata(default(string)));
[Bindable(true), Category("Content")]
public string FooterStringFormat
{
get => (string) GetValue(FooterStringFormatProperty);
set => SetValue(FooterStringFormatProperty, value);
}
}
@@ -2,45 +2,44 @@
using System.Windows;
using HandyControl.Data;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class ChatBubble : SelectableItem
{
public class ChatBubble : SelectableItem
public static readonly DependencyProperty RoleProperty = DependencyProperty.Register(
"Role", typeof(ChatRoleType), typeof(ChatBubble), new PropertyMetadata(default(ChatRoleType)));
public ChatRoleType Role
{
public static readonly DependencyProperty RoleProperty = DependencyProperty.Register(
"Role", typeof(ChatRoleType), typeof(ChatBubble), new PropertyMetadata(default(ChatRoleType)));
public ChatRoleType Role
{
get => (ChatRoleType) GetValue(RoleProperty);
set => SetValue(RoleProperty, value);
}
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register(
"Type", typeof(ChatMessageType), typeof(ChatBubble), new PropertyMetadata(default(ChatMessageType)));
public ChatMessageType Type
{
get => (ChatMessageType) GetValue(TypeProperty);
set => SetValue(TypeProperty, value);
}
public static readonly DependencyProperty IsReadProperty = DependencyProperty.Register(
"IsRead", typeof(bool), typeof(ChatBubble), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsRead
{
get => (bool) GetValue(IsReadProperty);
set => SetValue(IsReadProperty, ValueBoxes.BooleanBox(value));
}
public Action<object> ReadAction { get; set; }
protected override void OnSelected(RoutedEventArgs e)
{
base.OnSelected(e);
IsRead = true;
ReadAction?.Invoke(Content);
}
get => (ChatRoleType) GetValue(RoleProperty);
set => SetValue(RoleProperty, value);
}
}
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register(
"Type", typeof(ChatMessageType), typeof(ChatBubble), new PropertyMetadata(default(ChatMessageType)));
public ChatMessageType Type
{
get => (ChatMessageType) GetValue(TypeProperty);
set => SetValue(TypeProperty, value);
}
public static readonly DependencyProperty IsReadProperty = DependencyProperty.Register(
"IsRead", typeof(bool), typeof(ChatBubble), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsRead
{
get => (bool) GetValue(IsReadProperty);
set => SetValue(IsReadProperty, ValueBoxes.BooleanBox(value));
}
public Action<object> ReadAction { get; set; }
protected override void OnSelected(RoutedEventArgs e)
{
base.OnSelected(e);
IsRead = true;
ReadAction?.Invoke(Content);
}
}
File diff suppressed because it is too large. Load diff
@@ -3,80 +3,79 @@ using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class Divider : Control
{
public class Divider : Control
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(object), typeof(Divider), new PropertyMetadata(default(object)));
public object Content
{
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(object), typeof(Divider), new PropertyMetadata(default(object)));
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(Divider), new PropertyMetadata(default(Orientation)));
public Orientation Orientation
{
get => (Orientation) GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register(
"ContentTemplate", typeof(DataTemplate), typeof(Divider), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ContentTemplate
{
get => (DataTemplate) GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
public static readonly DependencyProperty ContentStringFormatProperty = DependencyProperty.Register(
"ContentStringFormat", typeof(string), typeof(Divider), new PropertyMetadata(default(string)));
public string ContentStringFormat
{
get => (string) GetValue(ContentStringFormatProperty);
set => SetValue(ContentStringFormatProperty, value);
}
public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register(
"ContentTemplateSelector", typeof(DataTemplateSelector), typeof(Divider), new PropertyMetadata(default(DataTemplateSelector)));
public DataTemplateSelector ContentTemplateSelector
{
get => (DataTemplateSelector) GetValue(ContentTemplateSelectorProperty);
set => SetValue(ContentTemplateSelectorProperty, value);
}
public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register(
"LineStroke", typeof(Brush), typeof(Divider), new PropertyMetadata(default(Brush)));
public Brush LineStroke
{
get => (Brush) GetValue(LineStrokeProperty);
set => SetValue(LineStrokeProperty, value);
}
public static readonly DependencyProperty LineStrokeThicknessProperty = DependencyProperty.Register(
"LineStrokeThickness", typeof(double), typeof(Divider), new PropertyMetadata(ValueBoxes.Double1Box));
public double LineStrokeThickness
{
get => (double) GetValue(LineStrokeThicknessProperty);
set => SetValue(LineStrokeThicknessProperty, value);
}
public static readonly DependencyProperty LineStrokeDashArrayProperty = DependencyProperty.Register(
"LineStrokeDashArray", typeof(DoubleCollection), typeof(Divider), new PropertyMetadata(new DoubleCollection()));
public DoubleCollection LineStrokeDashArray
{
get => (DoubleCollection) GetValue(LineStrokeDashArrayProperty);
set => SetValue(LineStrokeDashArrayProperty, value);
}
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
}
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(Divider), new PropertyMetadata(default(Orientation)));
public Orientation Orientation
{
get => (Orientation) GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register(
"ContentTemplate", typeof(DataTemplate), typeof(Divider), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ContentTemplate
{
get => (DataTemplate) GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
public static readonly DependencyProperty ContentStringFormatProperty = DependencyProperty.Register(
"ContentStringFormat", typeof(string), typeof(Divider), new PropertyMetadata(default(string)));
public string ContentStringFormat
{
get => (string) GetValue(ContentStringFormatProperty);
set => SetValue(ContentStringFormatProperty, value);
}
public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register(
"ContentTemplateSelector", typeof(DataTemplateSelector), typeof(Divider), new PropertyMetadata(default(DataTemplateSelector)));
public DataTemplateSelector ContentTemplateSelector
{
get => (DataTemplateSelector) GetValue(ContentTemplateSelectorProperty);
set => SetValue(ContentTemplateSelectorProperty, value);
}
public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register(
"LineStroke", typeof(Brush), typeof(Divider), new PropertyMetadata(default(Brush)));
public Brush LineStroke
{
get => (Brush) GetValue(LineStrokeProperty);
set => SetValue(LineStrokeProperty, value);
}
public static readonly DependencyProperty LineStrokeThicknessProperty = DependencyProperty.Register(
"LineStrokeThickness", typeof(double), typeof(Divider), new PropertyMetadata(ValueBoxes.Double1Box));
public double LineStrokeThickness
{
get => (double) GetValue(LineStrokeThicknessProperty);
set => SetValue(LineStrokeThicknessProperty, value);
}
public static readonly DependencyProperty LineStrokeDashArrayProperty = DependencyProperty.Register(
"LineStrokeDashArray", typeof(DoubleCollection), typeof(Divider), new PropertyMetadata(new DoubleCollection()));
public DoubleCollection LineStrokeDashArray
{
get => (DoubleCollection) GetValue(LineStrokeDashArrayProperty);
set => SetValue(LineStrokeDashArrayProperty, value);
}
}
@@ -2,35 +2,34 @@
using System.Windows.Controls;
using HandyControl.Data;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class Empty : ContentControl
{
public class Empty : ContentControl
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
"Description", typeof(object), typeof(Empty), new PropertyMetadata(default(object)));
public object Description
{
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
"Description", typeof(object), typeof(Empty), new PropertyMetadata(default(object)));
public object Description
{
get => GetValue(DescriptionProperty);
set => SetValue(DescriptionProperty, value);
}
public static readonly DependencyProperty LogoProperty = DependencyProperty.Register(
"Logo", typeof(object), typeof(Empty), new PropertyMetadata(default(object)));
public object Logo
{
get => GetValue(LogoProperty);
set => SetValue(LogoProperty, value);
}
public static readonly DependencyProperty ShowEmptyProperty = DependencyProperty.RegisterAttached(
"ShowEmpty", typeof(bool), typeof(Empty), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits));
public static void SetShowEmpty(DependencyObject element, bool value)
=> element.SetValue(ShowEmptyProperty, ValueBoxes.BooleanBox(value));
public static bool GetShowEmpty(DependencyObject element)
=> (bool) element.GetValue(ShowEmptyProperty);
get => GetValue(DescriptionProperty);
set => SetValue(DescriptionProperty, value);
}
}
public static readonly DependencyProperty LogoProperty = DependencyProperty.Register(
"Logo", typeof(object), typeof(Empty), new PropertyMetadata(default(object)));
public object Logo
{
get => GetValue(LogoProperty);
set => SetValue(LogoProperty, value);
}
public static readonly DependencyProperty ShowEmptyProperty = DependencyProperty.RegisterAttached(
"ShowEmpty", typeof(bool), typeof(Empty), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits));
public static void SetShowEmpty(DependencyObject element, bool value)
=> element.SetValue(ShowEmptyProperty, ValueBoxes.BooleanBox(value));
public static bool GetShowEmpty(DependencyObject element)
=> (bool) element.GetValue(ShowEmptyProperty);
}
@@ -5,96 +5,95 @@ using HandyControl.Data;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class GotoTop : Button
{
public class GotoTop : Button
private Action _gotoTopAction;
private System.Windows.Controls.ScrollViewer _scrollViewer;
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
"Target", typeof(DependencyObject), typeof(GotoTop), new PropertyMetadata(default(DependencyObject)));
public DependencyObject Target
{
private Action _gotoTopAction;
get => (DependencyObject) GetValue(TargetProperty);
set => SetValue(TargetProperty, value);
}
private System.Windows.Controls.ScrollViewer _scrollViewer;
public GotoTop() => Loaded += (s, e) => CreateGotoAction(Target);
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
"Target", typeof(DependencyObject), typeof(GotoTop), new PropertyMetadata(default(DependencyObject)));
public DependencyObject Target
public virtual void CreateGotoAction(DependencyObject obj)
{
if (_scrollViewer != null)
{
get => (DependencyObject) GetValue(TargetProperty);
set => SetValue(TargetProperty, value);
_scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged;
}
public GotoTop() => Loaded += (s, e) => CreateGotoAction(Target);
public virtual void CreateGotoAction(DependencyObject obj)
_scrollViewer = VisualHelper.GetChild<System.Windows.Controls.ScrollViewer>(obj);
if (_scrollViewer != null)
{
if (_scrollViewer != null)
_scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged;
if (_scrollViewer is ScrollViewer scrollViewerHandy && Animated && scrollViewerHandy.IsInertiaEnabled)
{
_scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged;
_gotoTopAction = () => scrollViewerHandy.ScrollToTopInternal(AnimationTime);
}
_scrollViewer = VisualHelper.GetChild<System.Windows.Controls.ScrollViewer>(obj);
if (_scrollViewer != null)
else
{
_scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged;
if (_scrollViewer is ScrollViewer scrollViewerHandy && Animated && scrollViewerHandy.IsInertiaEnabled)
{
_gotoTopAction = () => scrollViewerHandy.ScrollToTopInternal(AnimationTime);
}
else
{
_gotoTopAction = () => _scrollViewer.ScrollToTop();
}
_gotoTopAction = () => _scrollViewer.ScrollToTop();
}
}
private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (AutoHiding)
{
this.Show(e.VerticalOffset >= HidingHeight);
}
}
public static readonly DependencyProperty AnimatedProperty = DependencyProperty.Register(
"Animated", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
public bool Animated
{
get => (bool) GetValue(AnimatedProperty);
set => SetValue(AnimatedProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty AnimationTimeProperty = DependencyProperty.Register(
"AnimationTime", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double200Box));
public double AnimationTime
{
get => (double) GetValue(AnimationTimeProperty);
set => SetValue(AnimationTimeProperty, value);
}
public static readonly DependencyProperty HidingHeightProperty = DependencyProperty.Register(
"HidingHeight", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double0Box));
public double HidingHeight
{
get => (double) GetValue(HidingHeightProperty);
set => SetValue(HidingHeightProperty, value);
}
public static readonly DependencyProperty AutoHidingProperty = DependencyProperty.Register(
"AutoHiding", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
public bool AutoHiding
{
get => (bool) GetValue(AutoHidingProperty);
set => SetValue(AutoHidingProperty, ValueBoxes.BooleanBox(value));
}
protected override void OnClick()
{
base.OnClick();
_gotoTopAction?.Invoke();
}
}
}
private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (AutoHiding)
{
this.Show(e.VerticalOffset >= HidingHeight);
}
}
public static readonly DependencyProperty AnimatedProperty = DependencyProperty.Register(
"Animated", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
public bool Animated
{
get => (bool) GetValue(AnimatedProperty);
set => SetValue(AnimatedProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty AnimationTimeProperty = DependencyProperty.Register(
"AnimationTime", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double200Box));
public double AnimationTime
{
get => (double) GetValue(AnimationTimeProperty);
set => SetValue(AnimationTimeProperty, value);
}
public static readonly DependencyProperty HidingHeightProperty = DependencyProperty.Register(
"HidingHeight", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double0Box));
public double HidingHeight
{
get => (double) GetValue(HidingHeightProperty);
set => SetValue(HidingHeightProperty, value);
}
public static readonly DependencyProperty AutoHidingProperty = DependencyProperty.Register(
"AutoHiding", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
public bool AutoHiding
{
get => (bool) GetValue(AutoHidingProperty);
set => SetValue(AutoHidingProperty, ValueBoxes.BooleanBox(value));
}
protected override void OnClick()
{
base.OnClick();
_gotoTopAction?.Invoke();
}
}
@@ -4,55 +4,54 @@ using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class Gravatar : ContentControl
{
public class Gravatar : ContentControl
public static readonly DependencyProperty GeneratorProperty = DependencyProperty.Register(
"Generator", typeof(IGravatarGenerator), typeof(Gravatar), new PropertyMetadata(new GithubGravatarGenerator()));
public IGravatarGenerator Generator
{
public static readonly DependencyProperty GeneratorProperty = DependencyProperty.Register(
"Generator", typeof(IGravatarGenerator), typeof(Gravatar), new PropertyMetadata(new GithubGravatarGenerator()));
public IGravatarGenerator Generator
{
get => (IGravatarGenerator) GetValue(GeneratorProperty);
set => SetValue(GeneratorProperty, value);
}
public static readonly DependencyProperty IdProperty = DependencyProperty.Register(
"Id", typeof(string), typeof(Gravatar), new PropertyMetadata(default(string), OnIdChanged));
private static void OnIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar) d;
if (ctl.Source != null) return;
ctl.Content = ctl.Generator.GetGravatar((string) e.NewValue);
}
public string Id
{
get => (string) GetValue(IdProperty);
set => SetValue(IdProperty, value);
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source", typeof(ImageSource), typeof(Gravatar), new PropertyMetadata(default(ImageSource), OnSourceChanged));
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar) d;
var v = (ImageSource) e.NewValue;
ctl.Background = v != null
? new ImageBrush(v)
{
Stretch = Stretch.UniformToFill
}
: ResourceHelper.GetResourceInternal<Brush>(ResourceToken.SecondaryRegionBrush);
}
public ImageSource Source
{
get => (ImageSource) GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
get => (IGravatarGenerator) GetValue(GeneratorProperty);
set => SetValue(GeneratorProperty, value);
}
}
public static readonly DependencyProperty IdProperty = DependencyProperty.Register(
"Id", typeof(string), typeof(Gravatar), new PropertyMetadata(default(string), OnIdChanged));
private static void OnIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar) d;
if (ctl.Source != null) return;
ctl.Content = ctl.Generator.GetGravatar((string) e.NewValue);
}
public string Id
{
get => (string) GetValue(IdProperty);
set => SetValue(IdProperty, value);
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source", typeof(ImageSource), typeof(Gravatar), new PropertyMetadata(default(ImageSource), OnSourceChanged));
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar) d;
var v = (ImageSource) e.NewValue;
ctl.Background = v != null
? new ImageBrush(v)
{
Stretch = Stretch.UniformToFill
}
: ResourceHelper.GetResourceInternal<Brush>(ResourceToken.SecondaryRegionBrush);
}
public ImageSource Source
{
get => (ImageSource) GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
}
@@ -7,154 +7,153 @@ using HandyControl.Interactivity;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
namespace HandyControl.Controls;
[TemplatePart(Name = ElementVisualBrush, Type = typeof(VisualBrush))]
public class Magnifier : AdornerElement
{
[TemplatePart(Name = ElementVisualBrush, Type = typeof(VisualBrush))]
public class Magnifier : AdornerElement
private AdornerContainer _adornerContainer;
private Size _viewboxSize;
private const string ElementVisualBrush = "PART_VisualBrush";
private VisualBrush _visualBrush = new();
private readonly TranslateTransform _translateTransform;
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register(
"HorizontalOffset", typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
public double HorizontalOffset
{
private AdornerContainer _adornerContainer;
get => (double) GetValue(HorizontalOffsetProperty);
set => SetValue(HorizontalOffsetProperty, value);
}
private Size _viewboxSize;
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register(
"VerticalOffset", typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
private const string ElementVisualBrush = "PART_VisualBrush";
public double VerticalOffset
{
get => (double) GetValue(VerticalOffsetProperty);
set => SetValue(VerticalOffsetProperty, value);
}
private VisualBrush _visualBrush = new();
public static Magnifier Default => new();
private readonly TranslateTransform _translateTransform;
public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(
"Scale", typeof(double), typeof(Magnifier), new PropertyMetadata(5.0, OnScaleChanged), ValidateHelper.IsInRangeOfPosDouble);
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register(
"HorizontalOffset", typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
private static void OnScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => ((Magnifier) d).UpdateViewboxSize();
public double HorizontalOffset
public double Scale
{
get => (double) GetValue(ScaleProperty);
set => SetValue(ScaleProperty, value);
}
public Magnifier()
{
_translateTransform = new TranslateTransform();
RenderTransform = _translateTransform;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var visualBrush = GetTemplateChild(ElementVisualBrush) as VisualBrush ?? new VisualBrush();
visualBrush.Viewbox = _visualBrush.Viewbox;
_visualBrush = visualBrush;
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
UpdateViewboxSize();
}
private void UpdateViewboxSize() => _viewboxSize = new Size(ActualWidth / Scale, ActualHeight / Scale);
protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
{
base.OnTargetChanged(element, isNew);
if (element == null) return;
if (!isNew)
{
get => (double) GetValue(HorizontalOffsetProperty);
set => SetValue(HorizontalOffsetProperty, value);
element.MouseEnter -= Element_MouseEnter;
element.MouseLeave -= Element_MouseLeave;
element.MouseMove -= Element_MouseMove;
ElementTarget = null;
}
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register(
"VerticalOffset", typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
public double VerticalOffset
else
{
get => (double) GetValue(VerticalOffsetProperty);
set => SetValue(VerticalOffsetProperty, value);
}
public static Magnifier Default => new();
public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(
"Scale", typeof(double), typeof(Magnifier), new PropertyMetadata(5.0, OnScaleChanged), ValidateHelper.IsInRangeOfPosDouble);
private static void OnScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => ((Magnifier) d).UpdateViewboxSize();
public double Scale
{
get => (double) GetValue(ScaleProperty);
set => SetValue(ScaleProperty, value);
}
public Magnifier()
{
_translateTransform = new TranslateTransform();
RenderTransform = _translateTransform;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var visualBrush = GetTemplateChild(ElementVisualBrush) as VisualBrush ?? new VisualBrush();
visualBrush.Viewbox = _visualBrush.Viewbox;
_visualBrush = visualBrush;
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
UpdateViewboxSize();
}
private void UpdateViewboxSize() => _viewboxSize = new Size(ActualWidth / Scale, ActualHeight / Scale);
protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
{
base.OnTargetChanged(element, isNew);
if (element == null) return;
if (!isNew)
{
element.MouseEnter -= Element_MouseEnter;
element.MouseLeave -= Element_MouseLeave;
element.MouseMove -= Element_MouseMove;
ElementTarget = null;
}
else
{
element.MouseEnter += Element_MouseEnter;
element.MouseLeave += Element_MouseLeave;
element.MouseMove += Element_MouseMove;
ElementTarget = element;
}
}
protected override void Dispose() => HideAdornerElement();
private void UpdateLocation()
{
var targetPoint = Mouse.GetPosition(Target);
var subX = targetPoint.X - _visualBrush.Viewbox.Width / 2;
var subY = targetPoint.Y - _visualBrush.Viewbox.Height / 2;
var targetVector = VisualTreeHelper.GetOffset(Target);
_visualBrush.Viewbox = new Rect(new Point(subX + targetVector.X, subY + targetVector.Y), _viewboxSize);
var adornerPoint = Mouse.GetPosition(_adornerContainer);
_translateTransform.X = adornerPoint.X + HorizontalOffset;
_translateTransform.Y = adornerPoint.Y + VerticalOffset;
}
private void Element_MouseMove(object sender, MouseEventArgs e) => UpdateLocation();
private void Element_MouseLeave(object sender, MouseEventArgs e) => HideAdornerElement();
private void Element_MouseEnter(object sender, MouseEventArgs e) => ShowAdornerElement();
private void HideAdornerElement()
{
if (_adornerContainer == null) return;
var layer = AdornerLayer.GetAdornerLayer(Target);
if (layer != null)
{
layer.Remove(_adornerContainer);
}
else if (_adornerContainer is { Parent: AdornerLayer parent })
{
parent.Remove(_adornerContainer);
}
if (_adornerContainer != null)
{
_adornerContainer.Child = null;
_adornerContainer = null;
}
}
private void ShowAdornerElement()
{
if (_adornerContainer == null)
{
var layer = AdornerLayer.GetAdornerLayer(Target);
if (layer == null) return;
_adornerContainer = new AdornerContainer(layer)
{
Child = this
};
layer.Add(_adornerContainer);
}
this.Show();
element.MouseEnter += Element_MouseEnter;
element.MouseLeave += Element_MouseLeave;
element.MouseMove += Element_MouseMove;
ElementTarget = element;
}
}
}
protected override void Dispose() => HideAdornerElement();
private void UpdateLocation()
{
var targetPoint = Mouse.GetPosition(Target);
var subX = targetPoint.X - _visualBrush.Viewbox.Width / 2;
var subY = targetPoint.Y - _visualBrush.Viewbox.Height / 2;
var targetVector = VisualTreeHelper.GetOffset(Target);
_visualBrush.Viewbox = new Rect(new Point(subX + targetVector.X, subY + targetVector.Y), _viewboxSize);
var adornerPoint = Mouse.GetPosition(_adornerContainer);
_translateTransform.X = adornerPoint.X + HorizontalOffset;
_translateTransform.Y = adornerPoint.Y + VerticalOffset;
}
private void Element_MouseMove(object sender, MouseEventArgs e) => UpdateLocation();
private void Element_MouseLeave(object sender, MouseEventArgs e) => HideAdornerElement();
private void Element_MouseEnter(object sender, MouseEventArgs e) => ShowAdornerElement();
private void HideAdornerElement()
{
if (_adornerContainer == null) return;
var layer = AdornerLayer.GetAdornerLayer(Target);
if (layer != null)
{
layer.Remove(_adornerContainer);
}
else if (_adornerContainer is { Parent: AdornerLayer parent })
{
parent.Remove(_adornerContainer);
}
if (_adornerContainer != null)
{
_adornerContainer.Child = null;
_adornerContainer = null;
}
}
private void ShowAdornerElement()
{
if (_adornerContainer == null)
{
var layer = AdornerLayer.GetAdornerLayer(Target);
if (layer == null) return;
_adornerContainer = new AdornerContainer(layer)
{
Child = this
};
layer.Add(_adornerContainer);
}
this.Show();
}
}
@@ -5,150 +5,149 @@ using System.Windows.Threading;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public sealed class Notification : System.Windows.Window
{
public sealed class Notification : System.Windows.Window
private const int WaitTime = 6;
/// <summary>
/// 计数
/// </summary>
private int _tickCount;
/// <summary>
/// 关闭计时器
/// </summary>
private DispatcherTimer _timerClose;
private ShowAnimation ShowAnimation { get; set; }
private bool _shouldBeClosed;
public Notification()
{
private const int WaitTime = 6;
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
/// <summary>
/// 计数
/// </summary>
private int _tickCount;
/// <summary>
/// 关闭计时器
/// </summary>
private DispatcherTimer _timerClose;
private ShowAnimation ShowAnimation { get; set; }
private bool _shouldBeClosed;
public Notification()
public static Notification Show(object content, ShowAnimation showAnimation = ShowAnimation.None, bool staysOpen = false)
{
var notification = new Notification
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
Content = content,
Opacity = 0,
ShowAnimation = showAnimation
};
notification.Show();
var desktopWorkingArea = SystemParameters.WorkArea;
var leftMax = desktopWorkingArea.Width - notification.ActualWidth;
var topMax = desktopWorkingArea.Height - notification.ActualHeight;
switch (showAnimation)
{
case ShowAnimation.None:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = topMax;
break;
case ShowAnimation.HorizontalMove:
notification.Opacity = 1;
notification.Left = desktopWorkingArea.Width;
notification.Top = topMax;
notification.BeginAnimation(LeftProperty, AnimationHelper.CreateAnimation(leftMax));
break;
case ShowAnimation.VerticalMove:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = desktopWorkingArea.Height;
notification.BeginAnimation(TopProperty, AnimationHelper.CreateAnimation(topMax));
break;
case ShowAnimation.Fade:
notification.Left = leftMax;
notification.Top = topMax;
notification.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(1));
break;
default:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = topMax;
break;
}
public static Notification Show(object content, ShowAnimation showAnimation = ShowAnimation.None, bool staysOpen = false)
if (!staysOpen) notification.StartTimer();
return notification;
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
if (_shouldBeClosed)
{
var notification = new Notification
{
Content = content,
Opacity = 0,
ShowAnimation = showAnimation
};
notification.Show();
var desktopWorkingArea = SystemParameters.WorkArea;
var leftMax = desktopWorkingArea.Width - notification.ActualWidth;
var topMax = desktopWorkingArea.Height - notification.ActualHeight;
switch (showAnimation)
{
case ShowAnimation.None:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = topMax;
break;
case ShowAnimation.HorizontalMove:
notification.Opacity = 1;
notification.Left = desktopWorkingArea.Width;
notification.Top = topMax;
notification.BeginAnimation(LeftProperty, AnimationHelper.CreateAnimation(leftMax));
break;
case ShowAnimation.VerticalMove:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = desktopWorkingArea.Height;
notification.BeginAnimation(TopProperty, AnimationHelper.CreateAnimation(topMax));
break;
case ShowAnimation.Fade:
notification.Left = leftMax;
notification.Top = topMax;
notification.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(1));
break;
default:
notification.Opacity = 1;
notification.Left = leftMax;
notification.Top = topMax;
break;
}
if (!staysOpen) notification.StartTimer();
return notification;
return;
}
var desktopWorkingArea = SystemParameters.WorkArea;
protected override void OnClosing(CancelEventArgs e)
switch (ShowAnimation)
{
base.OnClosing(e);
if (_shouldBeClosed)
case ShowAnimation.None:
break;
case ShowAnimation.HorizontalMove:
{
return;
var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Width);
animation.Completed += Animation_Completed;
BeginAnimation(LeftProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
var desktopWorkingArea = SystemParameters.WorkArea;
switch (ShowAnimation)
break;
case ShowAnimation.VerticalMove:
{
case ShowAnimation.None:
break;
case ShowAnimation.HorizontalMove:
{
var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Width);
animation.Completed += Animation_Completed;
BeginAnimation(LeftProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
break;
case ShowAnimation.VerticalMove:
{
var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Height);
animation.Completed += Animation_Completed;
BeginAnimation(TopProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
break;
case ShowAnimation.Fade:
{
var animation = AnimationHelper.CreateAnimation(0);
animation.Completed += Animation_Completed;
BeginAnimation(OpacityProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
break;
var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Height);
animation.Completed += Animation_Completed;
BeginAnimation(TopProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
}
private void Animation_Completed(object sender, EventArgs e) => Close();
/// <summary>
/// 开始计时器
/// </summary>
private void StartTimer()
{
_timerClose = new DispatcherTimer
break;
case ShowAnimation.Fade:
{
Interval = TimeSpan.FromSeconds(1)
};
_timerClose.Tick += delegate
{
if (IsMouseOver)
{
_tickCount = 0;
return;
}
_tickCount++;
if (_tickCount >= WaitTime) Close();
};
_timerClose.Start();
var animation = AnimationHelper.CreateAnimation(0);
animation.Completed += Animation_Completed;
BeginAnimation(OpacityProperty, animation);
e.Cancel = true;
_shouldBeClosed = true;
}
break;
}
}
}
private void Animation_Completed(object sender, EventArgs e) => Close();
/// <summary>
/// 开始计时器
/// </summary>
private void StartTimer()
{
_timerClose = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
_timerClose.Tick += delegate
{
if (IsMouseOver)
{
_tickCount = 0;
return;
}
_tickCount++;
if (_tickCount >= WaitTime) Close();
};
_timerClose.Start();
}
}
File diff suppressed because it is too large. Load diff
@@ -7,396 +7,395 @@ using HandyControl.Interactivity;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
namespace HandyControl.Controls;
/// <summary>
/// 页码
/// </summary>
[TemplatePart(Name = ElementButtonLeft, Type = typeof(Button))]
[TemplatePart(Name = ElementButtonRight, Type = typeof(Button))]
[TemplatePart(Name = ElementButtonFirst, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementMoreLeft, Type = typeof(FrameworkElement))]
[TemplatePart(Name = ElementPanelMain, Type = typeof(Panel))]
[TemplatePart(Name = ElementMoreRight, Type = typeof(FrameworkElement))]
[TemplatePart(Name = ElementButtonLast, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementButtonLast, Type = typeof(NumericUpDown))]
public class Pagination : Control
{
#region Constants
private const string ElementButtonLeft = "PART_ButtonLeft";
private const string ElementButtonRight = "PART_ButtonRight";
private const string ElementButtonFirst = "PART_ButtonFirst";
private const string ElementMoreLeft = "PART_MoreLeft";
private const string ElementPanelMain = "PART_PanelMain";
private const string ElementMoreRight = "PART_MoreRight";
private const string ElementButtonLast = "PART_ButtonLast";
private const string ElementJump = "PART_Jump";
#endregion Constants
#region Data
private Button _buttonLeft;
private Button _buttonRight;
private RadioButton _buttonFirst;
private FrameworkElement _moreLeft;
private Panel _panelMain;
private FrameworkElement _moreRight;
private RadioButton _buttonLast;
private NumericUpDown _jumpNumericUpDown;
private bool _appliedTemplate;
#endregion Data
#region Public Events
/// <summary>
/// 页码
/// 页面更新事件
/// </summary>
[TemplatePart(Name = ElementButtonLeft, Type = typeof(Button))]
[TemplatePart(Name = ElementButtonRight, Type = typeof(Button))]
[TemplatePart(Name = ElementButtonFirst, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementMoreLeft, Type = typeof(FrameworkElement))]
[TemplatePart(Name = ElementPanelMain, Type = typeof(Panel))]
[TemplatePart(Name = ElementMoreRight, Type = typeof(FrameworkElement))]
[TemplatePart(Name = ElementButtonLast, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementButtonLast, Type = typeof(NumericUpDown))]
public class Pagination : Control
public static readonly RoutedEvent PageUpdatedEvent =
EventManager.RegisterRoutedEvent("PageUpdated", RoutingStrategy.Bubble,
typeof(EventHandler<FunctionEventArgs<int>>), typeof(Pagination));
/// <summary>
/// 页面更新事件
/// </summary>
public event EventHandler<FunctionEventArgs<int>> PageUpdated
{
#region Constants
private const string ElementButtonLeft = "PART_ButtonLeft";
private const string ElementButtonRight = "PART_ButtonRight";
private const string ElementButtonFirst = "PART_ButtonFirst";
private const string ElementMoreLeft = "PART_MoreLeft";
private const string ElementPanelMain = "PART_PanelMain";
private const string ElementMoreRight = "PART_MoreRight";
private const string ElementButtonLast = "PART_ButtonLast";
private const string ElementJump = "PART_Jump";
#endregion Constants
#region Data
private Button _buttonLeft;
private Button _buttonRight;
private RadioButton _buttonFirst;
private FrameworkElement _moreLeft;
private Panel _panelMain;
private FrameworkElement _moreRight;
private RadioButton _buttonLast;
private NumericUpDown _jumpNumericUpDown;
private bool _appliedTemplate;
#endregion Data
#region Public Events
/// <summary>
/// 页面更新事件
/// </summary>
public static readonly RoutedEvent PageUpdatedEvent =
EventManager.RegisterRoutedEvent("PageUpdated", RoutingStrategy.Bubble,
typeof(EventHandler<FunctionEventArgs<int>>), typeof(Pagination));
/// <summary>
/// 页面更新事件
/// </summary>
public event EventHandler<FunctionEventArgs<int>> PageUpdated
{
add => AddHandler(PageUpdatedEvent, value);
remove => RemoveHandler(PageUpdatedEvent, value);
}
#endregion Public Events
public Pagination()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Prev, ButtonPrev_OnClick));
CommandBindings.Add(new CommandBinding(ControlCommands.Next, ButtonNext_OnClick));
CommandBindings.Add(new CommandBinding(ControlCommands.Selected, ToggleButton_OnChecked));
CommandBindings.Add(new CommandBinding(ControlCommands.Jump, (s, e) => PageIndex = (int) _jumpNumericUpDown.Value));
OnAutoHidingChanged(AutoHiding);
Update();
}
#region Public Properties
#region MaxPageCount
/// <summary>
/// 最大页数
/// </summary>
public static readonly DependencyProperty MaxPageCountProperty = DependencyProperty.Register(
"MaxPageCount", typeof(int), typeof(Pagination), new PropertyMetadata(ValueBoxes.Int1Box, OnMaxPageCountChanged, CoerceMaxPageCount), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static object CoerceMaxPageCount(DependencyObject d, object basevalue)
{
var intValue = (int) basevalue;
return intValue < 1 ? 1 : intValue;
}
private static void OnMaxPageCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
if (pagination.PageIndex > pagination.MaxPageCount)
{
pagination.PageIndex = pagination.MaxPageCount;
}
pagination.CoerceValue(PageIndexProperty);
pagination.OnAutoHidingChanged(pagination.AutoHiding);
pagination.Update();
}
}
/// <summary>
/// 最大页数
/// </summary>
public int MaxPageCount
{
get => (int) GetValue(MaxPageCountProperty);
set => SetValue(MaxPageCountProperty, value);
}
#endregion MaxPageCount
#region DataCountPerPage
/// <summary>
/// 每页的数据量
/// </summary>
public static readonly DependencyProperty DataCountPerPageProperty = DependencyProperty.Register(
"DataCountPerPage", typeof(int), typeof(Pagination), new PropertyMetadata(20, OnDataCountPerPageChanged),
ValidateHelper.IsInRangeOfPosInt);
private static void OnDataCountPerPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.Update();
}
}
/// <summary>
/// 每页的数据量
/// </summary>
public int DataCountPerPage
{
get => (int) GetValue(DataCountPerPageProperty);
set => SetValue(DataCountPerPageProperty, value);
}
#endregion
#region PageIndex
/// <summary>
/// 当前页
/// </summary>
public static readonly DependencyProperty PageIndexProperty = DependencyProperty.Register(
"PageIndex", typeof(int), typeof(Pagination), new PropertyMetadata(ValueBoxes.Int1Box, OnPageIndexChanged, CoercePageIndex), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static object CoercePageIndex(DependencyObject d, object basevalue)
{
if (d is not Pagination pagination) return 1;
var intValue = (int) basevalue;
return intValue < 1
? 1
: intValue > pagination.MaxPageCount
? pagination.MaxPageCount
: intValue;
}
private static void OnPageIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination && e.NewValue is int value)
{
pagination.Update();
pagination.RaiseEvent(new FunctionEventArgs<int>(PageUpdatedEvent, pagination)
{
Info = value
});
}
}
/// <summary>
/// 当前页
/// </summary>
public int PageIndex
{
get => (int) GetValue(PageIndexProperty);
set => SetValue(PageIndexProperty, value);
}
#endregion PageIndex
#region MaxPageInterval
/// <summary>
/// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示)
/// </summary>
public static readonly DependencyProperty MaxPageIntervalProperty = DependencyProperty.Register(
"MaxPageInterval", typeof(int), typeof(Pagination), new PropertyMetadata(3, OnMaxPageIntervalChanged), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static void OnMaxPageIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.Update();
}
}
/// <summary>
/// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示)
/// </summary>
public int MaxPageInterval
{
get => (int) GetValue(MaxPageIntervalProperty);
set => SetValue(MaxPageIntervalProperty, value);
}
#endregion MaxPageInterval
#region IsJumpEnabled
public static readonly DependencyProperty IsJumpEnabledProperty = DependencyProperty.Register(
"IsJumpEnabled", typeof(bool), typeof(Pagination), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsJumpEnabled
{
get => (bool) GetValue(IsJumpEnabledProperty);
set => SetValue(IsJumpEnabledProperty, ValueBoxes.BooleanBox(value));
}
#endregion
#region AutoHiding
public static readonly DependencyProperty AutoHidingProperty = DependencyProperty.Register(
"AutoHiding", typeof(bool), typeof(Pagination), new PropertyMetadata(ValueBoxes.TrueBox, OnAutoHidingChanged));
private static void OnAutoHidingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.OnAutoHidingChanged((bool) e.NewValue);
}
}
private void OnAutoHidingChanged(bool newValue) => this.Show(!newValue || MaxPageCount > 1);
public bool AutoHiding
{
get => (bool) GetValue(AutoHidingProperty);
set => SetValue(AutoHidingProperty, ValueBoxes.BooleanBox(value));
}
#endregion
#endregion
#region Public Methods
public override void OnApplyTemplate()
{
_appliedTemplate = false;
base.OnApplyTemplate();
_buttonLeft = GetTemplateChild(ElementButtonLeft) as Button;
_buttonRight = GetTemplateChild(ElementButtonRight) as Button;
_buttonFirst = GetTemplateChild(ElementButtonFirst) as RadioButton;
_moreLeft = GetTemplateChild(ElementMoreLeft) as FrameworkElement;
_panelMain = GetTemplateChild(ElementPanelMain) as Panel;
_moreRight = GetTemplateChild(ElementMoreRight) as FrameworkElement;
_buttonLast = GetTemplateChild(ElementButtonLast) as RadioButton;
_jumpNumericUpDown = GetTemplateChild(ElementJump) as NumericUpDown;
CheckNull();
_appliedTemplate = true;
Update();
}
#endregion Public Methods
#region Private Methods
private void CheckNull()
{
if (_buttonLeft == null || _buttonRight == null || _buttonFirst == null ||
_moreLeft == null || _panelMain == null || _moreRight == null ||
_buttonLast == null) throw new Exception();
}
/// <summary>
/// 更新
/// </summary>
private void Update()
{
if (!_appliedTemplate) return;
_buttonLeft.IsEnabled = PageIndex > 1;
_buttonRight.IsEnabled = PageIndex < MaxPageCount;
if (MaxPageInterval == 0)
{
_buttonFirst.Collapse();
_buttonLast.Collapse();
_moreLeft.Collapse();
_moreRight.Collapse();
_panelMain.Children.Clear();
var selectButton = CreateButton(PageIndex);
_panelMain.Children.Add(selectButton);
selectButton.IsChecked = true;
return;
}
_buttonFirst.Show();
_buttonLast.Show();
_moreLeft.Show();
_moreRight.Show();
//更新最后一页
if (MaxPageCount == 1)
{
_buttonLast.Collapse();
}
else
{
_buttonLast.Show();
_buttonLast.Content = MaxPageCount.ToString();
}
//更新省略号
var right = MaxPageCount - PageIndex;
var left = PageIndex - 1;
_moreRight.Show(right > MaxPageInterval);
_moreLeft.Show(left > MaxPageInterval);
//更新中间部分
_panelMain.Children.Clear();
if (PageIndex > 1 && PageIndex < MaxPageCount)
{
var selectButton = CreateButton(PageIndex);
_panelMain.Children.Add(selectButton);
selectButton.IsChecked = true;
}
else if (PageIndex == 1)
{
_buttonFirst.IsChecked = true;
}
else
{
_buttonLast.IsChecked = true;
}
var sub = PageIndex;
for (var i = 0; i < MaxPageInterval - 1; i++)
{
if (--sub > 1)
{
_panelMain.Children.Insert(0, CreateButton(sub));
}
else
{
break;
}
}
var add = PageIndex;
for (var i = 0; i < MaxPageInterval - 1; i++)
{
if (++add < MaxPageCount)
{
_panelMain.Children.Add(CreateButton(add));
}
else
{
break;
}
}
}
private void ButtonPrev_OnClick(object sender, RoutedEventArgs e) => PageIndex--;
private void ButtonNext_OnClick(object sender, RoutedEventArgs e) => PageIndex++;
private RadioButton CreateButton(int page)
{
return new()
{
Style = ResourceHelper.GetResourceInternal<Style>(ResourceToken.PaginationButtonStyle),
Content = page.ToString()
};
}
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is not RadioButton button) return;
if (button.IsChecked == false) return;
PageIndex = int.Parse(button.Content.ToString());
}
#endregion Private Methods
add => AddHandler(PageUpdatedEvent, value);
remove => RemoveHandler(PageUpdatedEvent, value);
}
}
#endregion Public Events
public Pagination()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Prev, ButtonPrev_OnClick));
CommandBindings.Add(new CommandBinding(ControlCommands.Next, ButtonNext_OnClick));
CommandBindings.Add(new CommandBinding(ControlCommands.Selected, ToggleButton_OnChecked));
CommandBindings.Add(new CommandBinding(ControlCommands.Jump, (s, e) => PageIndex = (int) _jumpNumericUpDown.Value));
OnAutoHidingChanged(AutoHiding);
Update();
}
#region Public Properties
#region MaxPageCount
/// <summary>
/// 最大页数
/// </summary>
public static readonly DependencyProperty MaxPageCountProperty = DependencyProperty.Register(
"MaxPageCount", typeof(int), typeof(Pagination), new PropertyMetadata(ValueBoxes.Int1Box, OnMaxPageCountChanged, CoerceMaxPageCount), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static object CoerceMaxPageCount(DependencyObject d, object basevalue)
{
var intValue = (int) basevalue;
return intValue < 1 ? 1 : intValue;
}
private static void OnMaxPageCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
if (pagination.PageIndex > pagination.MaxPageCount)
{
pagination.PageIndex = pagination.MaxPageCount;
}
pagination.CoerceValue(PageIndexProperty);
pagination.OnAutoHidingChanged(pagination.AutoHiding);
pagination.Update();
}
}
/// <summary>
/// 最大页数
/// </summary>
public int MaxPageCount
{
get => (int) GetValue(MaxPageCountProperty);
set => SetValue(MaxPageCountProperty, value);
}
#endregion MaxPageCount
#region DataCountPerPage
/// <summary>
/// 每页的数据量
/// </summary>
public static readonly DependencyProperty DataCountPerPageProperty = DependencyProperty.Register(
"DataCountPerPage", typeof(int), typeof(Pagination), new PropertyMetadata(20, OnDataCountPerPageChanged),
ValidateHelper.IsInRangeOfPosInt);
private static void OnDataCountPerPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.Update();
}
}
/// <summary>
/// 每页的数据量
/// </summary>
public int DataCountPerPage
{
get => (int) GetValue(DataCountPerPageProperty);
set => SetValue(DataCountPerPageProperty, value);
}
#endregion
#region PageIndex
/// <summary>
/// 当前页
/// </summary>
public static readonly DependencyProperty PageIndexProperty = DependencyProperty.Register(
"PageIndex", typeof(int), typeof(Pagination), new PropertyMetadata(ValueBoxes.Int1Box, OnPageIndexChanged, CoercePageIndex), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static object CoercePageIndex(DependencyObject d, object basevalue)
{
if (d is not Pagination pagination) return 1;
var intValue = (int) basevalue;
return intValue < 1
? 1
: intValue > pagination.MaxPageCount
? pagination.MaxPageCount
: intValue;
}
private static void OnPageIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination && e.NewValue is int value)
{
pagination.Update();
pagination.RaiseEvent(new FunctionEventArgs<int>(PageUpdatedEvent, pagination)
{
Info = value
});
}
}
/// <summary>
/// 当前页
/// </summary>
public int PageIndex
{
get => (int) GetValue(PageIndexProperty);
set => SetValue(PageIndexProperty, value);
}
#endregion PageIndex
#region MaxPageInterval
/// <summary>
/// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示)
/// </summary>
public static readonly DependencyProperty MaxPageIntervalProperty = DependencyProperty.Register(
"MaxPageInterval", typeof(int), typeof(Pagination), new PropertyMetadata(3, OnMaxPageIntervalChanged), ValidateHelper.IsInRangeOfPosIntIncludeZero);
private static void OnMaxPageIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.Update();
}
}
/// <summary>
/// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示)
/// </summary>
public int MaxPageInterval
{
get => (int) GetValue(MaxPageIntervalProperty);
set => SetValue(MaxPageIntervalProperty, value);
}
#endregion MaxPageInterval
#region IsJumpEnabled
public static readonly DependencyProperty IsJumpEnabledProperty = DependencyProperty.Register(
"IsJumpEnabled", typeof(bool), typeof(Pagination), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsJumpEnabled
{
get => (bool) GetValue(IsJumpEnabledProperty);
set => SetValue(IsJumpEnabledProperty, ValueBoxes.BooleanBox(value));
}
#endregion
#region AutoHiding
public static readonly DependencyProperty AutoHidingProperty = DependencyProperty.Register(
"AutoHiding", typeof(bool), typeof(Pagination), new PropertyMetadata(ValueBoxes.TrueBox, OnAutoHidingChanged));
private static void OnAutoHidingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Pagination pagination)
{
pagination.OnAutoHidingChanged((bool) e.NewValue);
}
}
private void OnAutoHidingChanged(bool newValue) => this.Show(!newValue || MaxPageCount > 1);
public bool AutoHiding
{
get => (bool) GetValue(AutoHidingProperty);
set => SetValue(AutoHidingProperty, ValueBoxes.BooleanBox(value));
}
#endregion
#endregion
#region Public Methods
public override void OnApplyTemplate()
{
_appliedTemplate = false;
base.OnApplyTemplate();
_buttonLeft = GetTemplateChild(ElementButtonLeft) as Button;
_buttonRight = GetTemplateChild(ElementButtonRight) as Button;
_buttonFirst = GetTemplateChild(ElementButtonFirst) as RadioButton;
_moreLeft = GetTemplateChild(ElementMoreLeft) as FrameworkElement;
_panelMain = GetTemplateChild(ElementPanelMain) as Panel;
_moreRight = GetTemplateChild(ElementMoreRight) as FrameworkElement;
_buttonLast = GetTemplateChild(ElementButtonLast) as RadioButton;
_jumpNumericUpDown = GetTemplateChild(ElementJump) as NumericUpDown;
CheckNull();
_appliedTemplate = true;
Update();
}
#endregion Public Methods
#region Private Methods
private void CheckNull()
{
if (_buttonLeft == null || _buttonRight == null || _buttonFirst == null ||
_moreLeft == null || _panelMain == null || _moreRight == null ||
_buttonLast == null) throw new Exception();
}
/// <summary>
/// 更新
/// </summary>
private void Update()
{
if (!_appliedTemplate) return;
_buttonLeft.IsEnabled = PageIndex > 1;
_buttonRight.IsEnabled = PageIndex < MaxPageCount;
if (MaxPageInterval == 0)
{
_buttonFirst.Collapse();
_buttonLast.Collapse();
_moreLeft.Collapse();
_moreRight.Collapse();
_panelMain.Children.Clear();
var selectButton = CreateButton(PageIndex);
_panelMain.Children.Add(selectButton);
selectButton.IsChecked = true;
return;
}
_buttonFirst.Show();
_buttonLast.Show();
_moreLeft.Show();
_moreRight.Show();
//更新最后一页
if (MaxPageCount == 1)
{
_buttonLast.Collapse();
}
else
{
_buttonLast.Show();
_buttonLast.Content = MaxPageCount.ToString();
}
//更新省略号
var right = MaxPageCount - PageIndex;
var left = PageIndex - 1;
_moreRight.Show(right > MaxPageInterval);
_moreLeft.Show(left > MaxPageInterval);
//更新中间部分
_panelMain.Children.Clear();
if (PageIndex > 1 && PageIndex < MaxPageCount)
{
var selectButton = CreateButton(PageIndex);
_panelMain.Children.Add(selectButton);
selectButton.IsChecked = true;
}
else if (PageIndex == 1)
{
_buttonFirst.IsChecked = true;
}
else
{
_buttonLast.IsChecked = true;
}
var sub = PageIndex;
for (var i = 0; i < MaxPageInterval - 1; i++)
{
if (--sub > 1)
{
_panelMain.Children.Insert(0, CreateButton(sub));
}
else
{
break;
}
}
var add = PageIndex;
for (var i = 0; i < MaxPageInterval - 1; i++)
{
if (++add < MaxPageCount)
{
_panelMain.Children.Add(CreateButton(add));
}
else
{
break;
}
}
}
private void ButtonPrev_OnClick(object sender, RoutedEventArgs e) => PageIndex--;
private void ButtonNext_OnClick(object sender, RoutedEventArgs e) => PageIndex++;
private RadioButton CreateButton(int page)
{
return new()
{
Style = ResourceHelper.GetResourceInternal<Style>(ResourceToken.PaginationButtonStyle),
Content = page.ToString()
};
}
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is not RadioButton button) return;
if (button.IsChecked == false) return;
PageIndex = int.Parse(button.Content.ToString());
}
#endregion Private Methods
}
@@ -7,323 +7,322 @@ using System.Windows.Input;
using HandyControl.Data;
using HandyControl.Data.Enum;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class Poptip : AdornerElement
{
public class Poptip : AdornerElement
private readonly Popup _popup;
public Poptip()
{
private readonly Popup _popup;
public Poptip()
_popup = new Popup
{
_popup = new Popup
{
AllowsTransparency = true,
Child = this,
Placement = PlacementMode.Relative
};
AllowsTransparency = true,
Child = this,
Placement = PlacementMode.Relative
};
_popup.SetBinding(DataContextProperty, new Binding(DataContextProperty.Name) { Source = this });
}
_popup.SetBinding(DataContextProperty, new Binding(DataContextProperty.Name) { Source = this });
}
public static readonly DependencyProperty HitModeProperty = DependencyProperty.RegisterAttached(
"HitMode", typeof(HitMode), typeof(Poptip), new PropertyMetadata(HitMode.Hover));
public static readonly DependencyProperty HitModeProperty = DependencyProperty.RegisterAttached(
"HitMode", typeof(HitMode), typeof(Poptip), new PropertyMetadata(HitMode.Hover));
public static void SetHitMode(DependencyObject element, HitMode value)
=> element.SetValue(HitModeProperty, value);
public static void SetHitMode(DependencyObject element, HitMode value)
=> element.SetValue(HitModeProperty, value);
public static HitMode GetHitMode(DependencyObject element)
=> (HitMode) element.GetValue(HitModeProperty);
public static HitMode GetHitMode(DependencyObject element)
=> (HitMode) element.GetValue(HitModeProperty);
public HitMode HitMode
public HitMode HitMode
{
get => (HitMode) GetValue(HitModeProperty);
set => SetValue(HitModeProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
"Content", typeof(object), typeof(Poptip), new PropertyMetadata(default, OnContentChanged));
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Poptip) return;
if (GetInstance(d) == null)
{
get => (HitMode) GetValue(HitModeProperty);
set => SetValue(HitModeProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
"Content", typeof(object), typeof(Poptip), new PropertyMetadata(default, OnContentChanged));
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Poptip) return;
if (GetInstance(d) == null)
{
SetInstance(d, Default);
SetIsInstance(d, false);
}
}
public static void SetContent(DependencyObject element, object value)
=> element.SetValue(ContentProperty, value);
public static object GetContent(DependencyObject element)
=> element.GetValue(ContentProperty);
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register(
"ContentTemplate", typeof(DataTemplate), typeof(Poptip), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ContentTemplate
{
get => (DataTemplate) GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
public static readonly DependencyProperty ContentStringFormatProperty = DependencyProperty.Register(
"ContentStringFormat", typeof(string), typeof(Poptip), new PropertyMetadata(default(string)));
public string ContentStringFormat
{
get => (string) GetValue(ContentStringFormatProperty);
set => SetValue(ContentStringFormatProperty, value);
}
public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register(
"ContentTemplateSelector", typeof(DataTemplateSelector), typeof(Poptip), new PropertyMetadata(default(DataTemplateSelector)));
public DataTemplateSelector ContentTemplateSelector
{
get => (DataTemplateSelector) GetValue(ContentTemplateSelectorProperty);
set => SetValue(ContentTemplateSelectorProperty, value);
}
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached(
"VerticalOffset", typeof(double), typeof(Poptip), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetVerticalOffset(DependencyObject element, double value)
{
element.SetValue(VerticalOffsetProperty, value);
}
public static double GetVerticalOffset(DependencyObject element)
{
return (double) element.GetValue(VerticalOffsetProperty);
}
public double VerticalOffset
{
get => (double) GetValue(VerticalOffsetProperty);
set => SetValue(VerticalOffsetProperty, value);
}
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached(
"HorizontalOffset", typeof(double), typeof(Poptip), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetHorizontalOffset(DependencyObject element, double value)
{
element.SetValue(HorizontalOffsetProperty, value);
}
public static double GetHorizontalOffset(DependencyObject element)
{
return (double) element.GetValue(HorizontalOffsetProperty);
}
public double HorizontalOffset
{
get => (double) GetValue(HorizontalOffsetProperty);
set => SetValue(HorizontalOffsetProperty, value);
}
public static readonly DependencyProperty PlacementTypeProperty = DependencyProperty.RegisterAttached(
"PlacementType", typeof(PlacementType), typeof(Poptip), new PropertyMetadata(PlacementType.Top));
public static void SetPlacement(DependencyObject element, PlacementType value)
=> element.SetValue(PlacementTypeProperty, value);
public static PlacementType GetPlacement(DependencyObject element)
=> (PlacementType) element.GetValue(PlacementTypeProperty);
public PlacementType PlacementType
{
get => (PlacementType) GetValue(PlacementTypeProperty);
set => SetValue(PlacementTypeProperty, value);
}
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.RegisterAttached(
"IsOpen", typeof(bool), typeof(Poptip), new PropertyMetadata(ValueBoxes.FalseBox, OnIsOpenChanged));
private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Poptip poptip)
{
poptip.SwitchPoptip((bool) e.NewValue);
}
else
{
((Poptip) GetInstance(d))?.SwitchPoptip((bool) e.NewValue);
}
}
public static void SetIsOpen(DependencyObject element, bool value)
=> element.SetValue(IsOpenProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsOpen(DependencyObject element)
=> (bool) element.GetValue(IsOpenProperty);
public bool IsOpen
{
get => (bool) GetValue(IsOpenProperty);
set => SetValue(IsOpenProperty, ValueBoxes.BooleanBox(value));
}
public static Poptip Default => new();
protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
{
base.OnTargetChanged(element, isNew);
if (element == null) return;
if (!isNew)
{
element.MouseEnter -= Element_MouseEnter;
element.MouseLeave -= Element_MouseLeave;
element.GotFocus -= Element_GotFocus;
element.LostFocus -= Element_LostFocus;
ElementTarget = null;
}
else
{
element.MouseEnter += Element_MouseEnter;
element.MouseLeave += Element_MouseLeave;
element.GotFocus += Element_GotFocus;
element.LostFocus += Element_LostFocus;
ElementTarget = element;
_popup.PlacementTarget = ElementTarget;
}
}
protected override void Dispose() => SwitchPoptip(false);
private void UpdateLocation()
{
var targetWidth = Target.RenderSize.Width;
var targetHeight = Target.RenderSize.Height;
Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var size = DesiredSize;
var width = size.Width;
var height = size.Height;
var offsetX = .0;
var offsetY = .0;
var poptip = (Poptip) GetInstance(Target);
var popupPlacement = poptip.PlacementType;
var popupOffsetX = poptip.HorizontalOffset;
var popupOffsetY = poptip.VerticalOffset;
switch (popupPlacement)
{
case PlacementType.LeftTop:
break;
case PlacementType.Left:
offsetY = -(height - targetHeight) * 0.5;
break;
case PlacementType.LeftBottom:
offsetY = -(height - targetHeight);
break;
case PlacementType.TopLeft:
offsetX = width;
offsetY = -height;
break;
case PlacementType.Top:
offsetX = (width + targetWidth) * 0.5;
offsetY = -height;
break;
case PlacementType.TopRight:
offsetX = targetWidth;
offsetY = -height;
break;
case PlacementType.RightTop:
offsetX = width + targetWidth;
break;
case PlacementType.Right:
offsetX = width + targetWidth;
offsetY = -(height - targetHeight) * 0.5;
break;
case PlacementType.RightBottom:
offsetX = width + targetWidth;
offsetY = -(height - targetHeight);
break;
case PlacementType.BottomLeft:
offsetX = width;
offsetY = targetHeight;
break;
case PlacementType.Bottom:
offsetX = (width + targetWidth) * 0.5;
offsetY = targetHeight;
break;
case PlacementType.BottomRight:
offsetX = targetWidth;
offsetY = targetHeight;
break;
default:
throw new ArgumentOutOfRangeException();
}
_popup.HorizontalOffset = offsetX + popupOffsetX;
_popup.VerticalOffset = offsetY + popupOffsetY;
}
private void SwitchPoptip(bool isShow)
{
if (isShow)
{
if (!GetIsInstance(Target))
{
SetCurrentValue(ContentProperty, GetContent(Target));
SetCurrentValue(PlacementTypeProperty, GetPlacement(Target));
SetCurrentValue(HitModeProperty, GetHitMode(Target));
SetCurrentValue(HorizontalOffsetProperty, GetHorizontalOffset(Target));
SetCurrentValue(VerticalOffsetProperty, GetVerticalOffset(Target));
SetCurrentValue(IsOpenProperty, GetIsOpen(Target));
}
_popup.PlacementTarget = Target;
UpdateLocation();
}
_popup.IsOpen = isShow;
Target.SetCurrentValue(IsOpenProperty, isShow);
}
private void Element_MouseEnter(object sender, MouseEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Hover) return;
SwitchPoptip(true);
}
private void Element_MouseLeave(object sender, MouseEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Hover) return;
SwitchPoptip(false);
}
private void Element_GotFocus(object sender, RoutedEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Focus) return;
SwitchPoptip(true);
}
private void Element_LostFocus(object sender, RoutedEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Focus) return;
SwitchPoptip(false);
SetInstance(d, Default);
SetIsInstance(d, false);
}
}
}
public static void SetContent(DependencyObject element, object value)
=> element.SetValue(ContentProperty, value);
public static object GetContent(DependencyObject element)
=> element.GetValue(ContentProperty);
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register(
"ContentTemplate", typeof(DataTemplate), typeof(Poptip), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ContentTemplate
{
get => (DataTemplate) GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
public static readonly DependencyProperty ContentStringFormatProperty = DependencyProperty.Register(
"ContentStringFormat", typeof(string), typeof(Poptip), new PropertyMetadata(default(string)));
public string ContentStringFormat
{
get => (string) GetValue(ContentStringFormatProperty);
set => SetValue(ContentStringFormatProperty, value);
}
public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register(
"ContentTemplateSelector", typeof(DataTemplateSelector), typeof(Poptip), new PropertyMetadata(default(DataTemplateSelector)));
public DataTemplateSelector ContentTemplateSelector
{
get => (DataTemplateSelector) GetValue(ContentTemplateSelectorProperty);
set => SetValue(ContentTemplateSelectorProperty, value);
}
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached(
"VerticalOffset", typeof(double), typeof(Poptip), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetVerticalOffset(DependencyObject element, double value)
{
element.SetValue(VerticalOffsetProperty, value);
}
public static double GetVerticalOffset(DependencyObject element)
{
return (double) element.GetValue(VerticalOffsetProperty);
}
public double VerticalOffset
{
get => (double) GetValue(VerticalOffsetProperty);
set => SetValue(VerticalOffsetProperty, value);
}
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached(
"HorizontalOffset", typeof(double), typeof(Poptip), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetHorizontalOffset(DependencyObject element, double value)
{
element.SetValue(HorizontalOffsetProperty, value);
}
public static double GetHorizontalOffset(DependencyObject element)
{
return (double) element.GetValue(HorizontalOffsetProperty);
}
public double HorizontalOffset
{
get => (double) GetValue(HorizontalOffsetProperty);
set => SetValue(HorizontalOffsetProperty, value);
}
public static readonly DependencyProperty PlacementTypeProperty = DependencyProperty.RegisterAttached(
"PlacementType", typeof(PlacementType), typeof(Poptip), new PropertyMetadata(PlacementType.Top));
public static void SetPlacement(DependencyObject element, PlacementType value)
=> element.SetValue(PlacementTypeProperty, value);
public static PlacementType GetPlacement(DependencyObject element)
=> (PlacementType) element.GetValue(PlacementTypeProperty);
public PlacementType PlacementType
{
get => (PlacementType) GetValue(PlacementTypeProperty);
set => SetValue(PlacementTypeProperty, value);
}
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.RegisterAttached(
"IsOpen", typeof(bool), typeof(Poptip), new PropertyMetadata(ValueBoxes.FalseBox, OnIsOpenChanged));
private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Poptip poptip)
{
poptip.SwitchPoptip((bool) e.NewValue);
}
else
{
((Poptip) GetInstance(d))?.SwitchPoptip((bool) e.NewValue);
}
}
public static void SetIsOpen(DependencyObject element, bool value)
=> element.SetValue(IsOpenProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsOpen(DependencyObject element)
=> (bool) element.GetValue(IsOpenProperty);
public bool IsOpen
{
get => (bool) GetValue(IsOpenProperty);
set => SetValue(IsOpenProperty, ValueBoxes.BooleanBox(value));
}
public static Poptip Default => new();
protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
{
base.OnTargetChanged(element, isNew);
if (element == null) return;
if (!isNew)
{
element.MouseEnter -= Element_MouseEnter;
element.MouseLeave -= Element_MouseLeave;
element.GotFocus -= Element_GotFocus;
element.LostFocus -= Element_LostFocus;
ElementTarget = null;
}
else
{
element.MouseEnter += Element_MouseEnter;
element.MouseLeave += Element_MouseLeave;
element.GotFocus += Element_GotFocus;
element.LostFocus += Element_LostFocus;
ElementTarget = element;
_popup.PlacementTarget = ElementTarget;
}
}
protected override void Dispose() => SwitchPoptip(false);
private void UpdateLocation()
{
var targetWidth = Target.RenderSize.Width;
var targetHeight = Target.RenderSize.Height;
Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var size = DesiredSize;
var width = size.Width;
var height = size.Height;
var offsetX = .0;
var offsetY = .0;
var poptip = (Poptip) GetInstance(Target);
var popupPlacement = poptip.PlacementType;
var popupOffsetX = poptip.HorizontalOffset;
var popupOffsetY = poptip.VerticalOffset;
switch (popupPlacement)
{
case PlacementType.LeftTop:
break;
case PlacementType.Left:
offsetY = -(height - targetHeight) * 0.5;
break;
case PlacementType.LeftBottom:
offsetY = -(height - targetHeight);
break;
case PlacementType.TopLeft:
offsetX = width;
offsetY = -height;
break;
case PlacementType.Top:
offsetX = (width + targetWidth) * 0.5;
offsetY = -height;
break;
case PlacementType.TopRight:
offsetX = targetWidth;
offsetY = -height;
break;
case PlacementType.RightTop:
offsetX = width + targetWidth;
break;
case PlacementType.Right:
offsetX = width + targetWidth;
offsetY = -(height - targetHeight) * 0.5;
break;
case PlacementType.RightBottom:
offsetX = width + targetWidth;
offsetY = -(height - targetHeight);
break;
case PlacementType.BottomLeft:
offsetX = width;
offsetY = targetHeight;
break;
case PlacementType.Bottom:
offsetX = (width + targetWidth) * 0.5;
offsetY = targetHeight;
break;
case PlacementType.BottomRight:
offsetX = targetWidth;
offsetY = targetHeight;
break;
default:
throw new ArgumentOutOfRangeException();
}
_popup.HorizontalOffset = offsetX + popupOffsetX;
_popup.VerticalOffset = offsetY + popupOffsetY;
}
private void SwitchPoptip(bool isShow)
{
if (isShow)
{
if (!GetIsInstance(Target))
{
SetCurrentValue(ContentProperty, GetContent(Target));
SetCurrentValue(PlacementTypeProperty, GetPlacement(Target));
SetCurrentValue(HitModeProperty, GetHitMode(Target));
SetCurrentValue(HorizontalOffsetProperty, GetHorizontalOffset(Target));
SetCurrentValue(VerticalOffsetProperty, GetVerticalOffset(Target));
SetCurrentValue(IsOpenProperty, GetIsOpen(Target));
}
_popup.PlacementTarget = Target;
UpdateLocation();
}
_popup.IsOpen = isShow;
Target.SetCurrentValue(IsOpenProperty, isShow);
}
private void Element_MouseEnter(object sender, MouseEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Hover) return;
SwitchPoptip(true);
}
private void Element_MouseLeave(object sender, MouseEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Hover) return;
SwitchPoptip(false);
}
private void Element_GotFocus(object sender, RoutedEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Focus) return;
SwitchPoptip(true);
}
private void Element_LostFocus(object sender, RoutedEventArgs e)
{
var hitMode = GetIsInstance(Target) ? HitMode : GetHitMode(Target);
if (hitMode != HitMode.Focus) return;
SwitchPoptip(false);
}
}
@@ -7,206 +7,205 @@ using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class ScrollViewer : System.Windows.Controls.ScrollViewer
{
public class ScrollViewer : System.Windows.Controls.ScrollViewer
private double _totalVerticalOffset;
private double _totalHorizontalOffset;
private bool _isRunning;
/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public static readonly DependencyProperty CanMouseWheelProperty = DependencyProperty.Register(
"CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.TrueBox));
/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public bool CanMouseWheel
{
private double _totalVerticalOffset;
get => (bool) GetValue(CanMouseWheelProperty);
set => SetValue(CanMouseWheelProperty, ValueBoxes.BooleanBox(value));
}
private double _totalHorizontalOffset;
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (!CanMouseWheel) return;
private bool _isRunning;
/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public static readonly DependencyProperty CanMouseWheelProperty = DependencyProperty.Register(
"CanMouseWheel", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.TrueBox));
/// <summary>
/// 是否响应鼠标滚轮操作
/// </summary>
public bool CanMouseWheel
if (!IsInertiaEnabled)
{
get => (bool) GetValue(CanMouseWheelProperty);
set => SetValue(CanMouseWheelProperty, ValueBoxes.BooleanBox(value));
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (!CanMouseWheel) return;
if (!IsInertiaEnabled)
{
if (ScrollViewerAttach.GetOrientation(this) == Orientation.Vertical)
{
base.OnMouseWheel(e);
}
else
{
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
_totalHorizontalOffset = Math.Min(Math.Max(0, _totalHorizontalOffset - e.Delta), ScrollableWidth);
CurrentHorizontalOffset = _totalHorizontalOffset;
}
return;
}
e.Handled = true;
if (ScrollViewerAttach.GetOrientation(this) == Orientation.Vertical)
{
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
_totalVerticalOffset = Math.Min(Math.Max(0, _totalVerticalOffset - e.Delta), ScrollableHeight);
ScrollToVerticalOffsetWithAnimation(_totalVerticalOffset);
base.OnMouseWheel(e);
}
else
{
if (!_isRunning)
{
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
}
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
_totalHorizontalOffset = Math.Min(Math.Max(0, _totalHorizontalOffset - e.Delta), ScrollableWidth);
ScrollToHorizontalOffsetWithAnimation(_totalHorizontalOffset);
CurrentHorizontalOffset = _totalHorizontalOffset;
}
return;
}
e.Handled = true;
internal void ScrollToTopInternal(double milliseconds = 500)
if (ScrollViewerAttach.GetOrientation(this) == Orientation.Vertical)
{
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
ScrollToVerticalOffsetWithAnimation(0, milliseconds);
_totalVerticalOffset = Math.Min(Math.Max(0, _totalVerticalOffset - e.Delta), ScrollableHeight);
ScrollToVerticalOffsetWithAnimation(_totalVerticalOffset);
}
public void ScrollToVerticalOffsetWithAnimation(double offset, double milliseconds = 500)
else
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
if (!_isRunning)
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentVerticalOffset = offset;
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentVerticalOffsetProperty, animation, HandoffBehavior.Compose);
}
public void ScrollToHorizontalOffsetWithAnimation(double offset, double milliseconds = 500)
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentHorizontalOffset = offset;
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentHorizontalOffsetProperty, animation, HandoffBehavior.Compose);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) =>
IsPenetrating ? null : base.HitTestCore(hitTestParameters);
/// <summary>
/// 是否支持惯性
/// </summary>
public static readonly DependencyProperty IsInertiaEnabledProperty = DependencyProperty.RegisterAttached(
"IsInertiaEnabled", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));
public static void SetIsInertiaEnabled(DependencyObject element, bool value) => element.SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsInertiaEnabled(DependencyObject element) => (bool) element.GetValue(IsInertiaEnabledProperty);
/// <summary>
/// 是否支持惯性
/// </summary>
public bool IsInertiaEnabled
{
get => (bool) GetValue(IsInertiaEnabledProperty);
set => SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));
}
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.RegisterAttached(
"IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public bool IsPenetrating
{
get => (bool) GetValue(IsPenetratingProperty);
set => SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));
}
public static void SetIsPenetrating(DependencyObject element, bool value) => element.SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsPenetrating(DependencyObject element) => (bool) element.GetValue(IsPenetratingProperty);
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
"CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged));
private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToVerticalOffset(v);
_totalHorizontalOffset = HorizontalOffset;
CurrentHorizontalOffset = HorizontalOffset;
}
}
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal double CurrentVerticalOffset
{
// ReSharper disable once UnusedMember.Local
get => (double) GetValue(CurrentVerticalOffsetProperty);
set => SetValue(CurrentVerticalOffsetProperty, value);
}
/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register(
"CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged));
private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToHorizontalOffset(v);
}
}
/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal double CurrentHorizontalOffset
{
get => (double) GetValue(CurrentHorizontalOffsetProperty);
set => SetValue(CurrentHorizontalOffsetProperty, value);
_totalHorizontalOffset = Math.Min(Math.Max(0, _totalHorizontalOffset - e.Delta), ScrollableWidth);
ScrollToHorizontalOffsetWithAnimation(_totalHorizontalOffset);
}
}
}
internal void ScrollToTopInternal(double milliseconds = 500)
{
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
ScrollToVerticalOffsetWithAnimation(0, milliseconds);
}
public void ScrollToVerticalOffsetWithAnimation(double offset, double milliseconds = 500)
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentVerticalOffset = offset;
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentVerticalOffsetProperty, animation, HandoffBehavior.Compose);
}
public void ScrollToHorizontalOffsetWithAnimation(double offset, double milliseconds = 500)
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s, e1) =>
{
CurrentHorizontalOffset = offset;
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentHorizontalOffsetProperty, animation, HandoffBehavior.Compose);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) =>
IsPenetrating ? null : base.HitTestCore(hitTestParameters);
/// <summary>
/// 是否支持惯性
/// </summary>
public static readonly DependencyProperty IsInertiaEnabledProperty = DependencyProperty.RegisterAttached(
"IsInertiaEnabled", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));
public static void SetIsInertiaEnabled(DependencyObject element, bool value) => element.SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsInertiaEnabled(DependencyObject element) => (bool) element.GetValue(IsInertiaEnabledProperty);
/// <summary>
/// 是否支持惯性
/// </summary>
public bool IsInertiaEnabled
{
get => (bool) GetValue(IsInertiaEnabledProperty);
set => SetValue(IsInertiaEnabledProperty, ValueBoxes.BooleanBox(value));
}
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.RegisterAttached(
"IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public bool IsPenetrating
{
get => (bool) GetValue(IsPenetratingProperty);
set => SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));
}
public static void SetIsPenetrating(DependencyObject element, bool value) => element.SetValue(IsPenetratingProperty, ValueBoxes.BooleanBox(value));
public static bool GetIsPenetrating(DependencyObject element) => (bool) element.GetValue(IsPenetratingProperty);
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
"CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged));
private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToVerticalOffset(v);
}
}
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
internal double CurrentVerticalOffset
{
// ReSharper disable once UnusedMember.Local
get => (double) GetValue(CurrentVerticalOffsetProperty);
set => SetValue(CurrentVerticalOffsetProperty, value);
}
/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register(
"CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged));
private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToHorizontalOffset(v);
}
}
/// <summary>
/// 当前水平滚动偏移
/// </summary>
internal double CurrentHorizontalOffset
{
get => (double) GetValue(CurrentHorizontalOffsetProperty);
set => SetValue(CurrentHorizontalOffsetProperty, value);
}
}
@@ -3,36 +3,35 @@ using System.Windows.Controls.Primitives;
using System.Windows.Markup;
using System.Windows.Media;
namespace HandyControl.Controls
namespace HandyControl.Controls;
[ContentProperty(nameof(Status))]
public class Shield : ButtonBase
{
[ContentProperty(nameof(Status))]
public class Shield : ButtonBase
public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register(
"Subject", typeof(string), typeof(Shield), new PropertyMetadata(default(string)));
public string Subject
{
public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register(
"Subject", typeof(string), typeof(Shield), new PropertyMetadata(default(string)));
public string Subject
{
get => (string) GetValue(SubjectProperty);
set => SetValue(SubjectProperty, value);
}
public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
"Status", typeof(object), typeof(Shield), new PropertyMetadata(default(object)));
public object Status
{
get => GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
}
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
"Color", typeof(Brush), typeof(Shield), new PropertyMetadata(default(Brush)));
public Brush Color
{
get => (Brush) GetValue(ColorProperty);
set => SetValue(ColorProperty, value);
}
get => (string) GetValue(SubjectProperty);
set => SetValue(SubjectProperty, value);
}
}
public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
"Status", typeof(object), typeof(Shield), new PropertyMetadata(default(object)));
public object Status
{
get => GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
}
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
"Color", typeof(Brush), typeof(Shield), new PropertyMetadata(default(Brush)));
public Brush Color
{
get => (Brush) GetValue(ColorProperty);
set => SetValue(ColorProperty, value);
}
}
@@ -1,29 +1,28 @@
using System.Windows;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public sealed class Sprite : System.Windows.Window
{
public sealed class Sprite : System.Windows.Window
private Sprite()
{
private Sprite()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
public static Sprite Show(object content)
{
var sprite = new Sprite
{
Content = content
};
sprite.Show();
var desktopWorkingArea = SystemParameters.WorkArea;
sprite.Left = desktopWorkingArea.Width - sprite.ActualWidth - 50;
sprite.Top = 50 - sprite.Padding.Top;
return sprite;
}
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
}
public static Sprite Show(object content)
{
var sprite = new Sprite
{
Content = content
};
sprite.Show();
var desktopWorkingArea = SystemParameters.WorkArea;
sprite.Left = desktopWorkingArea.Width - sprite.ActualWidth - 50;
sprite.Top = 50 - sprite.Padding.Top;
return sprite;
}
}
@@ -5,104 +5,103 @@ using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
namespace HandyControl.Controls;
public class TransitioningContentControl : ContentControl
{
public class TransitioningContentControl : ContentControl
private FrameworkElement _contentPresenter;
private static Storyboard StoryboardBuildInDefault;
private Storyboard _storyboardBuildIn;
public TransitioningContentControl()
{
private FrameworkElement _contentPresenter;
Loaded += TransitioningContentControl_Loaded;
Unloaded += TransitioningContentControl_Unloaded;
}
private static Storyboard StoryboardBuildInDefault;
public static readonly DependencyProperty TransitionModeProperty = DependencyProperty.Register(
"TransitionMode", typeof(TransitionMode), typeof(TransitioningContentControl), new PropertyMetadata(default(TransitionMode), OnTransitionModeChanged));
private Storyboard _storyboardBuildIn;
private static void OnTransitionModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TransitioningContentControl) d;
ctl.OnTransitionModeChanged((TransitionMode) e.NewValue);
}
public TransitioningContentControl()
private void OnTransitionModeChanged(TransitionMode newValue)
{
_storyboardBuildIn = ResourceHelper.GetResourceInternal<Storyboard>($"{newValue}Transition");
StartTransition();
}
public TransitionMode TransitionMode
{
get => (TransitionMode) GetValue(TransitionModeProperty);
set => SetValue(TransitionModeProperty, value);
}
public static readonly DependencyProperty TransitionStoryboardProperty = DependencyProperty.Register(
"TransitionStoryboard", typeof(Storyboard), typeof(TransitioningContentControl), new PropertyMetadata(default(Storyboard)));
public Storyboard TransitionStoryboard
{
get => (Storyboard) GetValue(TransitionStoryboardProperty);
set => SetValue(TransitionStoryboardProperty, value);
}
private void TransitioningContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) => StartTransition();
private void TransitioningContentControl_Loaded(object sender, RoutedEventArgs e)
{
IsVisibleChanged += TransitioningContentControl_IsVisibleChanged;
}
private void TransitioningContentControl_Unloaded(object sender, RoutedEventArgs e)
{
IsVisibleChanged -= TransitioningContentControl_IsVisibleChanged;
}
private void StartTransition()
{
if (_contentPresenter == null || !IsVisible) return;
if (TransitionStoryboard != null)
{
Loaded += TransitioningContentControl_Loaded;
Unloaded += TransitioningContentControl_Unloaded;
TransitionStoryboard.Begin(_contentPresenter);
}
public static readonly DependencyProperty TransitionModeProperty = DependencyProperty.Register(
"TransitionMode", typeof(TransitionMode), typeof(TransitioningContentControl), new PropertyMetadata(default(TransitionMode), OnTransitionModeChanged));
private static void OnTransitionModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
else if (_storyboardBuildIn != null)
{
var ctl = (TransitioningContentControl) d;
ctl.OnTransitionModeChanged((TransitionMode) e.NewValue);
_storyboardBuildIn?.Begin(_contentPresenter);
}
private void OnTransitionModeChanged(TransitionMode newValue)
else
{
_storyboardBuildIn = ResourceHelper.GetResourceInternal<Storyboard>($"{newValue}Transition");
StartTransition();
}
public TransitionMode TransitionMode
{
get => (TransitionMode) GetValue(TransitionModeProperty);
set => SetValue(TransitionModeProperty, value);
}
public static readonly DependencyProperty TransitionStoryboardProperty = DependencyProperty.Register(
"TransitionStoryboard", typeof(Storyboard), typeof(TransitioningContentControl), new PropertyMetadata(default(Storyboard)));
public Storyboard TransitionStoryboard
{
get => (Storyboard) GetValue(TransitionStoryboardProperty);
set => SetValue(TransitionStoryboardProperty, value);
}
private void TransitioningContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) => StartTransition();
private void TransitioningContentControl_Loaded(object sender, RoutedEventArgs e)
{
IsVisibleChanged += TransitioningContentControl_IsVisibleChanged;
}
private void TransitioningContentControl_Unloaded(object sender, RoutedEventArgs e)
{
IsVisibleChanged -= TransitioningContentControl_IsVisibleChanged;
}
private void StartTransition()
{
if (_contentPresenter == null || !IsVisible) return;
if (TransitionStoryboard != null)
{
TransitionStoryboard.Begin(_contentPresenter);
}
else if (_storyboardBuildIn != null)
{
_storyboardBuildIn?.Begin(_contentPresenter);
}
else
{
StoryboardBuildInDefault ??= ResourceHelper.GetResourceInternal<Storyboard>($"{default(TransitionMode)}Transition");
StoryboardBuildInDefault?.Begin(_contentPresenter);
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_contentPresenter = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
if (_contentPresenter != null)
{
_contentPresenter.RenderTransformOrigin = new Point(0.5, 0.5);
_contentPresenter.RenderTransform = new TransformGroup
{
Children =
{
new ScaleTransform(),
new SkewTransform(),
new RotateTransform(),
new TranslateTransform()
}
};
}
StartTransition();
StoryboardBuildInDefault ??= ResourceHelper.GetResourceInternal<Storyboard>($"{default(TransitionMode)}Transition");
StoryboardBuildInDefault?.Begin(_contentPresenter);
}
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_contentPresenter = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
if (_contentPresenter != null)
{
_contentPresenter.RenderTransformOrigin = new Point(0.5, 0.5);
_contentPresenter.RenderTransform = new TransformGroup
{
Children =
{
new ScaleTransform(),
new SkewTransform(),
new RotateTransform(),
new TranslateTransform()
}
};
}
StartTransition();
}
}
@@ -5,161 +5,160 @@ using System.Windows.Media;
using System.Windows.Shapes;
using HandyControl.Data;
namespace HandyControl.Controls
namespace HandyControl.Controls;
[TemplatePart(Name = ElementRoot, Type = typeof(Border))]
[ContentProperty(nameof(Content))]
public class Watermark : Control
{
[TemplatePart(Name = ElementRoot, Type = typeof(Border))]
[ContentProperty(nameof(Content))]
public class Watermark : Control
private const string ElementRoot = "PART_Root";
private Border _borderRoot;
private DrawingBrush _brush;
public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
"Angle", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double Angle
{
private const string ElementRoot = "PART_Root";
private Border _borderRoot;
private DrawingBrush _brush;
public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
"Angle", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double Angle
{
get => (double) GetValue(AngleProperty);
set => SetValue(AngleProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(object), typeof(Watermark), new PropertyMetadata(default));
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty MarkProperty = DependencyProperty.Register(
"Mark", typeof(object), typeof(Watermark), new FrameworkPropertyMetadata(default, FrameworkPropertyMetadataOptions.AffectsRender));
public object Mark
{
get => GetValue(MarkProperty);
set => SetValue(MarkProperty, value);
}
public static readonly DependencyProperty MarkWidthProperty = DependencyProperty.Register(
"MarkWidth", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double MarkWidth
{
get => (double) GetValue(MarkWidthProperty);
set => SetValue(MarkWidthProperty, value);
}
public static readonly DependencyProperty MarkHeightProperty = DependencyProperty.Register(
"MarkHeight", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double MarkHeight
{
get => (double) GetValue(MarkHeightProperty);
set => SetValue(MarkHeightProperty, value);
}
public static readonly DependencyProperty MarkBrushProperty = DependencyProperty.Register(
"MarkBrush", typeof(Brush), typeof(Watermark), new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
public Brush MarkBrush
{
get => (Brush) GetValue(MarkBrushProperty);
set => SetValue(MarkBrushProperty, value);
}
public static readonly DependencyProperty AutoSizeEnabledProperty = DependencyProperty.Register(
"AutoSizeEnabled", typeof(bool), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.AffectsRender));
public bool AutoSizeEnabled
{
get => (bool) GetValue(AutoSizeEnabledProperty);
set => SetValue(AutoSizeEnabledProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty MarkMarginProperty = DependencyProperty.Register(
"MarkMargin", typeof(Thickness), typeof(Watermark), new FrameworkPropertyMetadata(default(Thickness), FrameworkPropertyMetadataOptions.AffectsRender));
public Thickness MarkMargin
{
get => (Thickness) GetValue(MarkMarginProperty);
set => SetValue(MarkMarginProperty, value);
}
public override void OnApplyTemplate() => _borderRoot = GetTemplateChild(ElementRoot) as Border;
private void EnsureBrush()
{
var presenter = new ContentPresenter();
if (Mark is Geometry geometry)
{
presenter.Content = new Path
{
Width = MarkWidth,
Height = MarkHeight,
Fill = MarkBrush,
Stretch = Stretch.Uniform,
Data = geometry
};
}
else if (Mark is string str)
{
presenter.Content = new TextBlock
{
Text = str,
FontSize = FontSize,
Foreground = MarkBrush
};
}
else
{
presenter.Content = Mark;
}
Size markSize;
if (AutoSizeEnabled)
{
presenter.Measure(new Size(double.MaxValue, double.MaxValue));
markSize = presenter.DesiredSize;
}
else
{
markSize = new Size(MarkWidth, MarkHeight);
}
_brush = new DrawingBrush
{
ViewportUnits = BrushMappingMode.Absolute,
Stretch = Stretch.Uniform,
TileMode = TileMode.Tile,
Transform = new RotateTransform(Angle),
Drawing = new GeometryDrawing
{
Brush = new VisualBrush(new Border
{
Background = Brushes.Transparent,
Padding = MarkMargin,
Child = presenter
}),
Geometry = new RectangleGeometry(new Rect(markSize))
},
Viewport = new Rect(markSize)
};
RenderOptions.SetCacheInvalidationThresholdMinimum(_brush, 0.5);
RenderOptions.SetCacheInvalidationThresholdMaximum(_brush, 2);
RenderOptions.SetCachingHint(_brush, CachingHint.Cache);
if (_borderRoot != null)
{
_borderRoot.Background = _brush;
}
}
protected override void OnRender(DrawingContext drawingContext) => EnsureBrush();
get => (double) GetValue(AngleProperty);
set => SetValue(AngleProperty, value);
}
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(object), typeof(Watermark), new PropertyMetadata(default));
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty MarkProperty = DependencyProperty.Register(
"Mark", typeof(object), typeof(Watermark), new FrameworkPropertyMetadata(default, FrameworkPropertyMetadataOptions.AffectsRender));
public object Mark
{
get => GetValue(MarkProperty);
set => SetValue(MarkProperty, value);
}
public static readonly DependencyProperty MarkWidthProperty = DependencyProperty.Register(
"MarkWidth", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double MarkWidth
{
get => (double) GetValue(MarkWidthProperty);
set => SetValue(MarkWidthProperty, value);
}
public static readonly DependencyProperty MarkHeightProperty = DependencyProperty.Register(
"MarkHeight", typeof(double), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double MarkHeight
{
get => (double) GetValue(MarkHeightProperty);
set => SetValue(MarkHeightProperty, value);
}
public static readonly DependencyProperty MarkBrushProperty = DependencyProperty.Register(
"MarkBrush", typeof(Brush), typeof(Watermark), new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
public Brush MarkBrush
{
get => (Brush) GetValue(MarkBrushProperty);
set => SetValue(MarkBrushProperty, value);
}
public static readonly DependencyProperty AutoSizeEnabledProperty = DependencyProperty.Register(
"AutoSizeEnabled", typeof(bool), typeof(Watermark), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.AffectsRender));
public bool AutoSizeEnabled
{
get => (bool) GetValue(AutoSizeEnabledProperty);
set => SetValue(AutoSizeEnabledProperty, ValueBoxes.BooleanBox(value));
}
public static readonly DependencyProperty MarkMarginProperty = DependencyProperty.Register(
"MarkMargin", typeof(Thickness), typeof(Watermark), new FrameworkPropertyMetadata(default(Thickness), FrameworkPropertyMetadataOptions.AffectsRender));
public Thickness MarkMargin
{
get => (Thickness) GetValue(MarkMarginProperty);
set => SetValue(MarkMarginProperty, value);
}
public override void OnApplyTemplate() => _borderRoot = GetTemplateChild(ElementRoot) as Border;
private void EnsureBrush()
{
var presenter = new ContentPresenter();
if (Mark is Geometry geometry)
{
presenter.Content = new Path
{
Width = MarkWidth,
Height = MarkHeight,
Fill = MarkBrush,
Stretch = Stretch.Uniform,
Data = geometry
};
}
else if (Mark is string str)
{
presenter.Content = new TextBlock
{
Text = str,
FontSize = FontSize,
Foreground = MarkBrush
};
}
else
{
presenter.Content = Mark;
}
Size markSize;
if (AutoSizeEnabled)
{
presenter.Measure(new Size(double.MaxValue, double.MaxValue));
markSize = presenter.DesiredSize;
}
else
{
markSize = new Size(MarkWidth, MarkHeight);
}
_brush = new DrawingBrush
{
ViewportUnits = BrushMappingMode.Absolute,
Stretch = Stretch.Uniform,
TileMode = TileMode.Tile,
Transform = new RotateTransform(Angle),
Drawing = new GeometryDrawing
{
Brush = new VisualBrush(new Border
{
Background = Brushes.Transparent,
Padding = MarkMargin,
Child = presenter
}),
Geometry = new RectangleGeometry(new Rect(markSize))
},
Viewport = new Rect(markSize)
};
RenderOptions.SetCacheInvalidationThresholdMinimum(_brush, 0.5);
RenderOptions.SetCacheInvalidationThresholdMaximum(_brush, 2);
RenderOptions.SetCachingHint(_brush, CachingHint.Cache);
if (_borderRoot != null)
{
_borderRoot.Background = _brush;
}
}
protected override void OnRender(DrawingContext drawingContext) => EnsureBrush();
}