Merge branch 'master' into pr/84

This commit is contained in:
NaBian committed 2019-11-03 20:18:22 +08:00
commit e02b420634
375 files changed
+9510 -1366

No files matched your search

@@ -8,6 +8,44 @@ namespace HandyControl.Controls
{
public class DataGridAttach
{
public static readonly DependencyProperty ApplyDefaultStyleProperty = DependencyProperty.RegisterAttached(
"ApplyDefaultStyle", typeof(bool), typeof(DataGridAttach), new PropertyMetadata(ValueBoxes.FalseBox, OnApplyDefaultStyleChanged));
private static void OnApplyDefaultStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = (DataGrid)d;
if ((bool)e.NewValue)
{
if (grid.AutoGenerateColumns)
{
grid.AutoGeneratedColumns += Grid_AutoGeneratedColumns;
return;
}
UpdateTextColumnStyles(grid);
UpdateComboBoxColumnStyles(grid);
UpdateCheckBoxColumnStyles(grid);
}
else
{
grid.AutoGeneratedColumns -= Grid_AutoGeneratedColumns;
}
}
private static void Grid_AutoGeneratedColumns(object sender, System.EventArgs e)
{
var grid = (DataGrid)sender;
UpdateTextColumnStyles(grid);
UpdateComboBoxColumnStyles(grid);
UpdateCheckBoxColumnStyles(grid);
}
public static void SetApplyDefaultStyle(DependencyObject element, bool value)
=> element.SetValue(ApplyDefaultStyleProperty, value);
public static bool GetApplyDefaultStyle(DependencyObject element)
=> (bool) element.GetValue(ApplyDefaultStyleProperty);
public static readonly DependencyProperty TextColumnStyleProperty = DependencyProperty.RegisterAttached(
"TextColumnStyle", typeof(Style), typeof(DataGridAttach), new PropertyMetadata(default(Style), OnTextColumnStyleChanged));
@@ -44,5 +44,29 @@ namespace HandyControl.Controls
public static void SetContentHeight(DependencyObject element, double value) => element.SetValue(ContentHeightProperty, value);
public static double GetContentHeight(DependencyObject element) => (double)element.GetValue(ContentHeightProperty);
/// <summary>
/// 最小内容高度
/// </summary>
public static readonly DependencyProperty MinContentHeightProperty = DependencyProperty.RegisterAttached(
"MinContentHeight", typeof(double), typeof(InfoElement), new PropertyMetadata(30.0));
public static void SetMinContentHeight(DependencyObject element, double value)
=> element.SetValue(MinContentHeightProperty, value);
public static double GetMinContentHeight(DependencyObject element)
=> (double) element.GetValue(MinContentHeightProperty);
/// <summary>
/// 最大内容高度
/// </summary>
public static readonly DependencyProperty MaxContentHeightProperty = DependencyProperty.RegisterAttached(
"MaxContentHeight", typeof(double), typeof(InfoElement), new PropertyMetadata(double.PositiveInfinity));
public static void SetMaxContentHeight(DependencyObject element, double value)
=> element.SetValue(MaxContentHeightProperty, value);
public static double GetMaxContentHeight(DependencyObject element)
=> (double) element.GetValue(MaxContentHeightProperty);
}
}
@@ -0,0 +1,53 @@
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class TextBlockAttach
{
public static readonly DependencyProperty AutoTooltipProperty = DependencyProperty.RegisterAttached(
"AutoTooltip", typeof(bool), typeof(TextBlockAttach), new PropertyMetadata(ValueBoxes.FalseBox, OnAutoTooltipChanged));
private static void OnAutoTooltipChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBlock ctl)
{
if ((bool)e.NewValue)
{
ctl.TextTrimming = TextTrimming.WordEllipsis;
UpdateTooltip(ctl);
ctl.SizeChanged += TextBlock_SizeChanged;
}
else
{
ctl.ClearValue(TextBlock.TextTrimmingProperty);
ctl.SizeChanged -= TextBlock_SizeChanged;
}
}
}
public static void SetAutoTooltip(DependencyObject element, bool value)
=> element.SetValue(AutoTooltipProperty, value);
public static bool GetAutoTooltip(DependencyObject element)
=> (bool) element.GetValue(AutoTooltipProperty);
private static void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (sender is TextBlock textBlock)
{
UpdateTooltip(textBlock);
}
}
private static void UpdateTooltip(TextBlock textBlock)
{
textBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var width = textBlock.DesiredSize.Width - textBlock.Margin.Left - textBlock.Margin.Right;
ToolTipService.SetToolTip(textBlock,
textBlock.RenderSize.Width > width || textBlock.ActualWidth < width ? textBlock.Text : null);
}
}
}
@@ -1,6 +1,9 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using HandyControl.Data;
using HandyControl.Tools.Interop;
namespace HandyControl.Controls
{
@@ -21,7 +24,7 @@ namespace HandyControl.Controls
{
if ((bool)e.NewValue)
{
ctl.MouseLeftButtonDown += DragElement_MouseLeftButtonDown; ;
ctl.MouseLeftButtonDown += DragElement_MouseLeftButtonDown;
}
else
{
@@ -37,5 +40,72 @@ namespace HandyControl.Controls
System.Windows.Window.GetWindow(obj)?.DragMove();
}
}
public static readonly DependencyProperty IgnoreAltF4Property = DependencyProperty.RegisterAttached(
"IgnoreAltF4", typeof(bool), typeof(WindowAttach), new PropertyMetadata(ValueBoxes.FalseBox, OnIgnoreAltF4Changed));
private static void OnIgnoreAltF4Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is System.Windows.Window window)
{
if ((bool)e.NewValue)
{
window.PreviewKeyDown += Window_PreviewKeyDown;
}
else
{
window.PreviewKeyDown -= Window_PreviewKeyDown;
}
}
}
private static void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.System && e.SystemKey == Key.F4)
{
e.Handled = true;
}
}
public static void SetIgnoreAltF4(DependencyObject element, bool value)
=> element.SetValue(IgnoreAltF4Property, value);
public static bool GetIgnoreAltF4(DependencyObject element)
=> (bool) element.GetValue(IgnoreAltF4Property);
public static readonly DependencyProperty ShowInTaskManagerProperty = DependencyProperty.RegisterAttached(
"ShowInTaskManager", typeof(bool), typeof(WindowAttach), new PropertyMetadata(ValueBoxes.TrueBox, OnShowInTaskManagerChanged));
private static void OnShowInTaskManagerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is System.Windows.Window window)
{
if ((bool)e.NewValue)
{
window.SourceInitialized -= Window_SourceInitialized;
}
else
{
window.SourceInitialized += Window_SourceInitialized;
}
}
}
private static void Window_SourceInitialized(object sender, EventArgs e)
{
if (sender is System.Windows.Window window)
{
var _ = new WindowInteropHelper(window)
{
Owner = NativeMethods.GetDesktopWindow()
};
}
}
public static void SetShowInTaskManager(DependencyObject element, bool value)
=> element.SetValue(ShowInTaskManagerProperty, value);
public static bool GetShowInTaskManager(DependencyObject element)
=> (bool) element.GetValue(ShowInTaskManagerProperty);
}
}
@@ -0,0 +1,188 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Interactivity;
using HandyControl.Tools;
namespace HandyControl.Controls
{
public class FloatingBlock : Control
{
public static readonly DependencyProperty ToXProperty = DependencyProperty.RegisterAttached(
"ToX", typeof(double), typeof(FloatingBlock), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetToX(DependencyObject element, double value)
=> element.SetValue(ToXProperty, value);
public static double GetToX(DependencyObject element)
=> (double) element.GetValue(ToXProperty);
public static readonly DependencyProperty ToYProperty = DependencyProperty.RegisterAttached(
"ToY", typeof(double), typeof(FloatingBlock), new PropertyMetadata(-100.0));
public static void SetToY(DependencyObject element, double value)
=> element.SetValue(ToYProperty, value);
public static double GetToY(DependencyObject element)
=> (double)element.GetValue(ToYProperty);
public static readonly DependencyProperty DurationProperty = DependencyProperty.RegisterAttached(
"Duration", typeof(Duration), typeof(FloatingBlock), new PropertyMetadata(new Duration(TimeSpan.FromSeconds(2))));
public static void SetDuration(DependencyObject element, Duration value)
=> element.SetValue(DurationProperty, value);
public static Duration GetDuration(DependencyObject element)
=> (Duration) element.GetValue(DurationProperty);
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached(
"HorizontalOffset", typeof(double), typeof(FloatingBlock), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetHorizontalOffset(DependencyObject element, double value)
=> element.SetValue(HorizontalOffsetProperty, value);
public static double GetHorizontalOffset(DependencyObject element)
=> (double) element.GetValue(HorizontalOffsetProperty);
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached(
"VerticalOffset", typeof(double), typeof(FloatingBlock), new PropertyMetadata(ValueBoxes.Double0Box));
public static void SetVerticalOffset(DependencyObject element, double value)
=> element.SetValue(VerticalOffsetProperty, value);
public static double GetVerticalOffset(DependencyObject element)
=> (double) element.GetValue(VerticalOffsetProperty);
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.RegisterAttached(
"ContentTemplate", typeof(DataTemplate), typeof(FloatingBlock), new PropertyMetadata(default(DataTemplate), OnDataChanged));
public static void SetContentTemplate(DependencyObject element, DataTemplate value)
=> element.SetValue(ContentTemplateProperty, value);
public static DataTemplate GetContentTemplate(DependencyObject element)
=> (DataTemplate) element.GetValue(ContentTemplateProperty);
public DataTemplate ContentTemplate
{
get => (DataTemplate)GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
private static readonly DependencyProperty ReadyToFloatProperty = DependencyProperty.RegisterAttached(
"ReadyToFloat", typeof(bool), typeof(FloatingBlock), new PropertyMetadata(ValueBoxes.FalseBox));
private static void SetReadyToFloat(DependencyObject element, bool value)
=> element.SetValue(ReadyToFloatProperty, value);
private static bool GetReadyToFloat(DependencyObject element)
=> (bool)element.GetValue(ReadyToFloatProperty);
public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
"Content", typeof(object), typeof(FloatingBlock), new PropertyMetadata(default, OnDataChanged));
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);
}
private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is UIElement target)) return;
target.PreviewMouseLeftButtonDown -= Target_PreviewMouseLeftButtonDown;
target.PreviewMouseLeftButtonUp -= Target_PreviewMouseLeftButtonUp;
if (e.NewValue != null)
{
target.PreviewMouseLeftButtonDown += Target_PreviewMouseLeftButtonDown;
target.PreviewMouseLeftButtonUp += Target_PreviewMouseLeftButtonUp;
}
}
private static void Target_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) => SetReadyToFloat(sender as DependencyObject, true);
private static void Target_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (sender is UIElement element && GetReadyToFloat(element))
{
var layer = AdornerLayer.GetAdornerLayer(element);
if (layer != null)
{
var adorner = new AdornerContainer(layer)
{
IsHitTestVisible = false
};
var child = CreateBlock(element, adorner);
adorner.Child = child;
layer.Add(adorner);
}
SetReadyToFloat(element, false);
}
}
private static FloatingBlock CreateBlock(Visual element, AdornerContainer adorner)
{
var p = Mouse.GetPosition(adorner.AdornedElement);
var transform = new TranslateTransform
{
X = p.X + GetHorizontalOffset(element),
Y = p.Y + GetVerticalOffset(element)
};
var block = new FloatingBlock
{
Content = GetContent(element),
ContentTemplate = GetContentTemplate(element),
RenderTransform = new TransformGroup
{
Children =
{
transform
}
}
};
var milliseconds = GetDuration(element).TimeSpan.TotalMilliseconds;
var animationX = AnimationHelper.CreateAnimation(GetToX(element) + transform.X, milliseconds);
Storyboard.SetTargetProperty(animationX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)"));
Storyboard.SetTarget(animationX, block);
var animationY = AnimationHelper.CreateAnimation(GetToY(element) + transform.Y, milliseconds);
Storyboard.SetTargetProperty(animationY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
Storyboard.SetTarget(animationY, block);
var animationOpacity = AnimationHelper.CreateAnimation(0, milliseconds);
Storyboard.SetTargetProperty(animationOpacity, new PropertyPath("Opacity"));
Storyboard.SetTarget(animationOpacity, block);
var storyboard = new Storyboard();
storyboard.Completed += (s, e) =>
{
var layer = AdornerLayer.GetAdornerLayer(element);
if (layer == null) return;
adorner.Child = null;
layer.Remove(adorner);
};
storyboard.Children.Add(animationX);
storyboard.Children.Add(animationY);
storyboard.Children.Add(animationOpacity);
storyboard.Begin();
return block;
}
}
}
@@ -0,0 +1,172 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Data;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementContent, Type = typeof(FrameworkElement))]
[TemplatePart(Name = ElementPanel, Type = typeof(Panel))]
public class RunningBlock : ContentControl
{
private const string ElementContent = "PART_ContentElement";
private const string ElementPanel = "PART_Panel";
protected Storyboard _storyboard;
private FrameworkElement _elementContent;
private FrameworkElement _elementPanel;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_elementContent = GetTemplateChild(ElementContent) as FrameworkElement;
_elementPanel = GetTemplateChild(ElementPanel) as Panel;
}
public static readonly DependencyProperty RunawayProperty = DependencyProperty.Register(
"Runaway", typeof(bool), typeof(RunningBlock), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.AffectsRender));
public bool Runaway
{
get => (bool) GetValue(RunawayProperty);
set => SetValue(RunawayProperty, value);
}
public static readonly DependencyProperty AutoRunProperty = DependencyProperty.Register(
"AutoRun", typeof(bool), typeof(RunningBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender));
public bool AutoRun
{
get => (bool) GetValue(AutoRunProperty);
set => SetValue(AutoRunProperty, value);
}
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(RunningBlock), new FrameworkPropertyMetadata(default(Orientation), FrameworkPropertyMetadataOptions.AffectsRender));
public Orientation Orientation
{
get => (Orientation) GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
"Duration", typeof(Duration), typeof(RunningBlock), new FrameworkPropertyMetadata(new Duration(TimeSpan.FromSeconds(5)), FrameworkPropertyMetadataOptions.AffectsRender));
public Duration Duration
{
get => (Duration) GetValue(DurationProperty);
set => SetValue(DurationProperty, value);
}
public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register(
"IsRunning", typeof(bool), typeof(RunningBlock), new PropertyMetadata(ValueBoxes.TrueBox, (o, args) =>
{
var ctl = (RunningBlock)o;
var v = (bool)args.NewValue;
if (v)
{
ctl._storyboard?.Resume();
}
else
{
ctl._storyboard?.Pause();
}
}));
public bool IsRunning
{
get => (bool) GetValue(IsRunningProperty);
set => SetValue(IsRunningProperty, value);
}
public static readonly DependencyProperty AutoReverseProperty = DependencyProperty.Register(
"AutoReverse", typeof(bool), typeof(RunningBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender));
public bool AutoReverse
{
get => (bool) GetValue(AutoReverseProperty);
set => SetValue(AutoReverseProperty, value);
}
private void UpdateContent()
{
if (_elementContent == null || _elementPanel == null) return;
_storyboard?.Stop();
_elementPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
_elementPanel.Width = _elementPanel.DesiredSize.Width;
_elementPanel.Height = _elementPanel.DesiredSize.Height;
double from;
double to;
PropertyPath propertyPath;
if (Orientation == Orientation.Horizontal)
{
if (AutoRun && _elementPanel.Width < ActualWidth)
{
return;
}
if (Runaway)
{
from = -_elementPanel.Width;
to = ActualWidth;
}
else
{
from = 0;
to = ActualWidth - _elementPanel.Width;
SetCurrentValue(AutoReverseProperty, ValueBoxes.TrueBox);
}
propertyPath = new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)");
}
else
{
if (AutoRun && _elementPanel.Height < ActualHeight)
{
return;
}
if (Runaway)
{
from = -_elementPanel.Height;
to = ActualHeight;
}
else
{
from = 0;
to = ActualHeight - _elementPanel.Height;
SetCurrentValue(AutoReverseProperty, ValueBoxes.TrueBox);
}
propertyPath = new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)");
}
var animation = new DoubleAnimation(from, to, Duration)
{
RepeatBehavior = RepeatBehavior.Forever,
AutoReverse = AutoReverse
};
Storyboard.SetTargetProperty(animation, propertyPath);
Storyboard.SetTarget(animation, _elementContent);
_storyboard = new Storyboard();
_storyboard.Children.Add(animation);
_storyboard.Begin();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
UpdateContent();
}
}
}
@@ -0,0 +1,81 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using HandyControl.Data;
using HandyControl.Data.Enum;
namespace HandyControl.Controls
{
public class SplitButton : ButtonBase
{
public static readonly DependencyProperty HitModeProperty = DependencyProperty.Register(
"HitMode", typeof(MouseHitMode), typeof(SplitButton), new PropertyMetadata(default(MouseHitMode)));
public MouseHitMode HitMode
{
get => (MouseHitMode) GetValue(HitModeProperty);
set => SetValue(HitModeProperty, value);
}
public static readonly DependencyProperty MaxDropDownHeightProperty = DependencyProperty.Register(
"MaxDropDownHeight", typeof(double), typeof(SplitButton), new PropertyMetadata(SystemParameters.PrimaryScreenHeight / 3.0));
public double MaxDropDownHeight
{
get => (double) GetValue(MaxDropDownHeightProperty);
set => SetValue(MaxDropDownHeightProperty, value);
}
public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register(
"IsDropDownOpen", typeof(bool), typeof(SplitButton), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsDropDownOpen
{
get => (bool) GetValue(IsDropDownOpenProperty);
set => SetValue(IsDropDownOpenProperty, value);
}
public static readonly DependencyProperty DropDownContentProperty = DependencyProperty.Register(
"DropDownContent", typeof(object), typeof(SplitButton), new PropertyMetadata(default(object)));
public object DropDownContent
{
get => GetValue(DropDownContentProperty);
set => SetValue(DropDownContentProperty, value);
}
public SplitButton()
{
AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(ItemsOnClick));
}
private void ItemsOnClick(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is MenuItem)
{
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.FalseBox);
}
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnPreviewMouseLeftButtonDown(e);
if (HitMode == MouseHitMode.Hover)
{
e.Handled = true;
}
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
if (HitMode == MouseHitMode.Hover)
{
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.TrueBox);
}
}
}
}
@@ -223,7 +223,7 @@ namespace HandyControl.Controls
{
ItemsHost.Children.Remove(_viewContent);
}
var total = Items.Count + 1;
var total = _entryDic.Count + 1;
var totalRow = total / Groups + (total % Groups > 0 ? 1 : 0);
if (total <= Groups)
{
@@ -359,9 +359,9 @@ namespace HandyControl.Controls
private void GenerateIndex()
{
var index = 0;
foreach (var item in Items)
foreach (var item in _entryDic.Values)
{
_entryDic[item].Index = index++;
item.Index = index++;
}
}
@@ -1,4 +1,5 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
using HandyControl.Tools.Extension;
@@ -40,32 +41,48 @@ namespace HandyControl.Controls
set => SetValue(SpanProperty, value);
}
public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register(
"IsFixed", typeof(bool), typeof(Col), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsFixed
{
get => (bool) GetValue(IsFixedProperty);
set => SetValue(IsFixedProperty, value);
}
internal int GetLayoutCellCount(ColLayoutStatus status)
{
var result = 0;
if (Layout != null)
{
switch (status)
if (!IsFixed)
{
case ColLayoutStatus.Xs:
result = Layout.Xs;
break;
case ColLayoutStatus.Sm:
result = Layout.Sm;
break;
case ColLayoutStatus.Md:
result = Layout.Md;
break;
case ColLayoutStatus.Lg:
result = Layout.Lg;
break;
case ColLayoutStatus.Xl:
result = Layout.Xl;
break;
case ColLayoutStatus.Xxl:
result = Layout.Xxl;
break;
switch (status)
{
case ColLayoutStatus.Xs:
result = Layout.Xs;
break;
case ColLayoutStatus.Sm:
result = Layout.Sm;
break;
case ColLayoutStatus.Md:
result = Layout.Md;
break;
case ColLayoutStatus.Lg:
result = Layout.Lg;
break;
case ColLayoutStatus.Xl:
result = Layout.Xl;
break;
case ColLayoutStatus.Xxl:
result = Layout.Xxl;
break;
case ColLayoutStatus.Auto:
break;
default:
throw new ArgumentOutOfRangeException(nameof(status), status, null);
}
}
}
else
@@ -13,6 +13,8 @@ namespace HandyControl.Controls
private double _maxChildDesiredHeight;
private double _totalAutoWidth;
public static readonly DependencyProperty GutterProperty = DependencyProperty.Register(
"Gutter", typeof(double), typeof(Row), new PropertyMetadata(ValueBoxes.Double0Box, null, OnGutterCoerce), ValidateHelper.IsInRangeOfPosDoubleIncludeZero);
@@ -29,6 +31,7 @@ namespace HandyControl.Controls
var totalCellCount = 0;
var totalRowCount = 1;
var gutterHalf = Gutter / 2;
_totalAutoWidth = 0;
foreach (var child in InternalChildren.OfType<Col>())
{
@@ -40,12 +43,7 @@ namespace HandyControl.Controls
{
_maxChildDesiredHeight = childDesiredSize.Height;
}
}
_layoutStatus = ColLayout.GetLayoutStatus(constraint.Width);
foreach (var child in InternalChildren.OfType<Col>())
{
var cellCount = child.GetLayoutCellCount(_layoutStatus);
totalCellCount += cellCount;
@@ -54,16 +52,21 @@ namespace HandyControl.Controls
totalCellCount = cellCount;
totalRowCount++;
}
if (cellCount == 0 || child.IsFixed)
{
_totalAutoWidth += childDesiredSize.Width;
}
}
return new Size(0, _maxChildDesiredHeight * totalRowCount - Gutter);
return new Size(constraint.Width, _maxChildDesiredHeight * totalRowCount - Gutter);
}
protected override Size ArrangeOverride(Size finalSize)
{
var totalCellCount = 0;
var gutterHalf = Gutter / 2;
var itemWidth = (finalSize.Width + Gutter) / ColLayout.ColMaxCellCount;
var itemWidth = (finalSize.Width - _totalAutoWidth + Gutter) / ColLayout.ColMaxCellCount;
var childBounds = new Rect(-gutterHalf, -gutterHalf, 0, _maxChildDesiredHeight);
_layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width);
@@ -72,7 +75,8 @@ namespace HandyControl.Controls
var cellCount = child.GetLayoutCellCount(_layoutStatus);
totalCellCount += cellCount;
var childWidth = cellCount * itemWidth;
var childWidth = cellCount > 0 ? cellCount * itemWidth : child.DesiredSize.Width;
childBounds.Width = childWidth;
childBounds.X += child.Offset * itemWidth;
if (totalCellCount > ColLayout.ColMaxCellCount)
@@ -31,6 +31,8 @@ namespace HandyControl.Controls
#region Data
private static GrowlWindow GrowlWindow;
private Panel _panelMore;
private Grid _gridMain;
@@ -293,6 +295,8 @@ namespace HandyControl.Controls
private static void InitGrowlPanel(Panel panel)
{
if (panel == null) return;
var menuItem = new MenuItem
{
Header = Properties.Langs.Lang.Clear
@@ -334,6 +338,61 @@ namespace HandyControl.Controls
if (!_staysOpen) StartTimer();
}
private static void ShowGlobal(GrowlInfo growlInfo)
{
if (GrowlWindow == null)
{
GrowlWindow = new GrowlWindow();
GrowlWindow.Show();
InitGrowlPanel(GrowlWindow.GrowlPanel);
GrowlWindow.Init();
}
GrowlWindow.Show(true);
#if netle40
Application.Current.Dispatcher?.Invoke(new Action(() =>
{
var ctl = new Growl
{
Message = growlInfo.Message,
Time = DateTime.Now,
Icon = ResourceHelper.GetResource<Geometry>(growlInfo.IconKey),
IconBrush = ResourceHelper.GetResource<Brush>(growlInfo.IconBrushKey),
_showCloseButton = growlInfo.ShowCloseButton,
ActionBeforeClose = growlInfo.ActionBeforeClose,
_staysOpen = growlInfo.StaysOpen,
ShowDateTime = growlInfo.ShowDateTime,
ConfirmStr = growlInfo.ConfirmStr,
CancelStr = growlInfo.CancelStr,
Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, 2)
};
GrowlWindow.GrowlPanel.Children.Insert(0, ctl);
}));
#else
Application.Current.Dispatcher?.Invoke(() =>
{
var ctl = new Growl
{
Message = growlInfo.Message,
Time = DateTime.Now,
Icon = ResourceHelper.GetResource<Geometry>(growlInfo.IconKey),
IconBrush = ResourceHelper.GetResource<Brush>(growlInfo.IconBrushKey),
_showCloseButton = growlInfo.ShowCloseButton,
ActionBeforeClose = growlInfo.ActionBeforeClose,
_staysOpen = growlInfo.StaysOpen,
ShowDateTime = growlInfo.ShowDateTime,
ConfirmStr = growlInfo.ConfirmStr,
CancelStr = growlInfo.CancelStr,
Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, 2)
};
GrowlWindow.GrowlPanel.Children.Insert(0, ctl);
});
#endif
}
/// <summary>
/// 显示信息
/// </summary>
@@ -341,7 +400,7 @@ namespace HandyControl.Controls
private static void Show(GrowlInfo growlInfo)
{
#if netle40
Application.Current.Dispatcher.Invoke(new Action(() =>
Application.Current.Dispatcher?.Invoke(new Action(() =>
{
var ctl = new Growl
{
@@ -371,7 +430,7 @@ namespace HandyControl.Controls
}
}));
#else
Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher?.Invoke(() =>
{
var ctl = new Growl
{
@@ -430,6 +489,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 成功
/// </summary>
/// <param name="message"></param>
public static void SuccessGlobal(string message) => SuccessGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 成功
/// </summary>
/// <param name="growlInfo"></param>
public static void SuccessGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.SuccessGeometry;
growlInfo.IconBrushKey = ResourceToken.SuccessBrush;
growlInfo.Type = InfoType.Success;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 消息
/// </summary>
@@ -457,6 +541,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 消息
/// </summary>
/// <param name="message"></param>
public static void InfoGlobal(string message) => InfoGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 消息
/// </summary>
/// <param name="growlInfo"></param>
public static void InfoGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.InfoGeometry;
growlInfo.IconBrushKey = ResourceToken.InfoBrush;
growlInfo.Type = InfoType.Info;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 警告
/// </summary>
@@ -484,6 +593,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="message"></param>
public static void WarningGlobal(string message) => WarningGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 警告
/// </summary>
/// <param name="growlInfo"></param>
public static void WarningGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.WarningGeometry;
growlInfo.IconBrushKey = ResourceToken.WarningBrush;
growlInfo.Type = InfoType.Warning;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 错误
/// </summary>
@@ -512,6 +646,32 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="message"></param>
public static void ErrorGlobal(string message) => ErrorGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 错误
/// </summary>
/// <param name="growlInfo"></param>
public static void ErrorGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.ErrorGeometry;
growlInfo.IconBrushKey = ResourceToken.DangerBrush;
growlInfo.StaysOpen = true;
growlInfo.Type = InfoType.Error;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 严重
/// </summary>
@@ -542,6 +702,34 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 严重
/// </summary>
/// <param name="message"></param>
public static void FatalGlobal(string message) => FatalGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 严重
/// </summary>
/// <param name="growlInfo"></param>
public static void FatalGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.FatalGeometry;
growlInfo.IconBrushKey = ResourceToken.PrimaryTextBrush;
growlInfo.StaysOpen = true;
growlInfo.ShowCloseButton = false;
growlInfo.Type = InfoType.Fatal;
if (GrowlPanel.ContextMenu != null) GrowlPanel.ContextMenu.Opacity = 0;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 询问
/// </summary>
@@ -573,6 +761,35 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 询问
/// </summary>
/// <param name="message"></param>
/// <param name="actionBeforeClose"></param>
public static void AskGlobal(string message, Func<bool, bool> actionBeforeClose) => AskGlobal(new GrowlInfo
{
Message = message,
ActionBeforeClose = actionBeforeClose
});
/// <summary>
/// 询问
/// </summary>
/// <param name="growlInfo"></param>
public static void AskGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.AskGeometry;
growlInfo.IconBrushKey = ResourceToken.AccentBrush;
growlInfo.StaysOpen = true;
growlInfo.ShowCloseButton = false;
growlInfo.Type = InfoType.Ask;
}
ShowGlobal(growlInfo);
}
private void ButtonClose_OnClick(object sender, RoutedEventArgs e) => Close();
/// <summary>
@@ -589,6 +806,12 @@ namespace HandyControl.Controls
if (Parent is Panel panel)
{
panel.Children.Remove(this);
if (GrowlWindow?.GrowlPanel != null && GrowlWindow.GrowlPanel.Children.Count == 0)
{
GrowlWindow.Close();
GrowlWindow = null;
}
}
};
transform.BeginAnimation(TranslateTransform.XProperty, animation);
@@ -619,6 +842,7 @@ namespace HandyControl.Controls
/// <param name="panel"></param>
private static void Clear(Panel panel)
{
if (panel == null) return;
panel.Children.Clear();
if (panel.ContextMenu != null)
{
@@ -627,6 +851,17 @@ namespace HandyControl.Controls
}
}
/// <summary>
/// 清除
/// </summary>
public static void ClearGlobal()
{
if (GrowlWindow == null) return;
Clear(GrowlWindow.GrowlPanel);
GrowlWindow.Close();
GrowlWindow = null;
}
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e)
{
if (ActionBeforeClose?.Invoke(false) == true)
@@ -0,0 +1,34 @@
using System.Windows;
using System.Windows.Controls;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementGrowPanel, Type = typeof(Panel))]
internal class GrowlWindow : Window
{
private const string ElementGrowPanel = "PART_GrowPanel";
public Panel GrowlPanel { get; set; }
public GrowlWindow()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
GrowlPanel = GetTemplateChild(ElementGrowPanel) as Panel;
}
public void Init()
{
var desktopWorkingArea = SystemParameters.WorkArea;
Height = desktopWorkingArea.Height;
Left = desktopWorkingArea.Right - Width;
Top = 0;
}
}
}
@@ -83,6 +83,8 @@ namespace HandyControl.Controls
StartAnimate();
}
};
Unloaded += (s, e) => Dispose();
}
public GifImage(string filename)
@@ -25,7 +25,7 @@ namespace HandyControl.Controls
public ImageBlock()
{
_dispatcherTimer = new DispatcherTimer
_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Render)
{
Interval = Interval
};
@@ -187,4 +187,4 @@ namespace HandyControl.Controls
return rect;
}
}
}
}
@@ -43,10 +43,10 @@ namespace HandyControl.Controls
{
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(SelectedValueProperty);
ClearValue(SelectedItemProperty);
ClearValue(SelectedIndexProperty);
ClearValue(TextProperty);
SetCurrentValue(SelectedValueProperty, null);
SetCurrentValue(SelectedItemProperty, null);
SetCurrentValue(SelectedIndexProperty, -1);
SetCurrentValue(TextProperty, "");
}));
}
@@ -85,7 +85,7 @@ namespace HandyControl.Controls
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.OneWayToSource,
#if !netle40
Delay = 500,
Delay = 500,
#endif
Source = this
});
@@ -20,8 +20,8 @@ namespace HandyControl.Controls
{
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(SelectedDateProperty);
ClearValue(TextProperty);
SetCurrentValue(SelectedDateProperty, null);
SetCurrentValue(TextProperty, "");
}));
}
@@ -82,8 +82,8 @@ namespace HandyControl.Controls
InitCalendarWithClock();
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(SelectedDateTimeProperty);
ClearValue(TextProperty);
SetCurrentValue(SelectedDateTimeProperty, null);
SetCurrentValue(TextProperty, "");
_textBox.Text = string.Empty;
}));
}
@@ -147,7 +147,6 @@ namespace HandyControl.Controls
dp._calendarWithClock.Focus();
});
}
}
}
@@ -43,7 +43,7 @@ namespace HandyControl.Controls
}));
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(ValueProperty);
SetCurrentValue(ValueProperty, 0d);
_textBox.Text = string.Empty;
}));
@@ -65,7 +65,8 @@ namespace HandyControl.Controls
{
if (_textBox != null)
{
_textBox.TextChanged -= TextBox_TextChanged;
TextCompositionManager.RemovePreviewTextInputHandler(_textBox, PreviewTextInputHandler);
_textBox.TextChanged -= _textBox_TextChanged;
_textBox.PreviewKeyDown -= TextBox_PreviewKeyDown;
_textBox.LostFocus -= TextBox_LostFocus;
}
@@ -76,13 +77,27 @@ namespace HandyControl.Controls
if (_textBox != null)
{
_textBox.TextChanged += TextBox_TextChanged;
TextCompositionManager.AddPreviewTextInputHandler(_textBox, PreviewTextInputHandler);
_textBox.TextChanged += _textBox_TextChanged;
_textBox.PreviewKeyDown += TextBox_PreviewKeyDown;
_textBox.LostFocus += TextBox_LostFocus;
_textBox.Text = CurrentText;
}
}
private void _textBox_TextChanged(object sender, TextChangedEventArgs e) => UpdateData();
private void UpdateData()
{
if (!VerifyData()) return;
if (double.TryParse(_textBox.Text, out var value))
{
Value = value;
}
}
private void PreviewTextInputHandler(object sender, TextCompositionEventArgs e) => UpdateData();
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (IsError) return;
@@ -103,15 +118,6 @@ namespace HandyControl.Controls
}
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (!VerifyData()) return;
if (double.TryParse(_textBox.Text, out var value))
{
Value = value;
}
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
@@ -52,14 +52,16 @@ namespace HandyControl.Controls
Info = Text
});
if (Command == null) return;
if (Command is RoutedCommand command)
switch (Command)
{
command.Execute(CommandParameter, CommandTarget);
}
else
{
Command.Execute(CommandParameter);
case null:
return;
case RoutedCommand command:
command.Execute(CommandParameter, CommandTarget);
break;
default:
Command.Execute(CommandParameter);
break;
}
}
@@ -15,7 +15,7 @@ namespace HandyControl.Controls
{
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(TextProperty);
SetCurrentValue(TextProperty, "");
}));
}
@@ -80,8 +80,8 @@ namespace HandyControl.Controls
Clock = new Clock();
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(SelectedTimeProperty);
ClearValue(TextProperty);
SetCurrentValue(SelectedTimeProperty, null);
SetCurrentValue(TextProperty, "");
_textBox.Text = string.Empty;
}));
}
@@ -261,7 +261,7 @@ namespace HandyControl.Controls
public bool IsError
{
get => (bool) GetValue(IsErrorProperty);
get => (bool)GetValue(IsErrorProperty);
set => SetValue(IsErrorProperty, value);
}
@@ -270,7 +270,7 @@ namespace HandyControl.Controls
public string ErrorStr
{
get => (string) GetValue(ErrorStrProperty);
get => (string)GetValue(ErrorStrProperty);
set => SetValue(ErrorStrProperty, value);
}
@@ -279,7 +279,7 @@ namespace HandyControl.Controls
public TextType TextType
{
get => (TextType) GetValue(TextTypeProperty);
get => (TextType)GetValue(TextTypeProperty);
set => SetValue(TextTypeProperty, value);
}
@@ -288,7 +288,7 @@ namespace HandyControl.Controls
public bool ShowClearButton
{
get => (bool) GetValue(ShowClearButtonProperty);
get => (bool)GetValue(ShowClearButtonProperty);
set => SetValue(ShowClearButtonProperty, value);
}
@@ -297,7 +297,7 @@ namespace HandyControl.Controls
private static void OnClockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimePicker) d;
var ctl = (TimePicker)d;
var oldClock = e.OldValue as ClockBase;
var newClock = e.NewValue as ClockBase;
@@ -317,7 +317,7 @@ namespace HandyControl.Controls
public ClockBase Clock
{
get => (ClockBase) GetValue(ClockProperty);
get => (ClockBase)GetValue(ClockProperty);
set => SetValue(ClockProperty, value);
}
@@ -497,29 +497,29 @@ namespace HandyControl.Controls
switch (e.Key)
{
case Key.System:
{
switch (e.SystemKey)
{
case Key.Down:
switch (e.SystemKey)
{
if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
{
TogglePopUp();
return true;
}
case Key.Down:
{
if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
{
TogglePopUp();
return true;
}
break;
break;
}
}
break;
}
break;
}
case Key.Enter:
{
SetSelectedTime();
return true;
}
{
SetSelectedTime();
return true;
}
}
return false;
@@ -644,7 +644,7 @@ namespace HandyControl.Controls
if (SelectedTime != null)
{
var newtext = DateTimeToString((DateTime) SelectedTime);
var newtext = DateTimeToString((DateTime)SelectedTime);
SafeSetText(newtext);
return SelectedTime;
}
@@ -12,8 +12,6 @@ namespace HandyControl.Controls
{
public class AnimationPath : Shape
{
private bool _isLoaded;
/// <summary>
/// 故事板
/// </summary>
@@ -126,15 +124,7 @@ namespace HandyControl.Controls
OnPropertiesChanged));
}
public AnimationPath()
{
Loaded += (s, e) =>
{
if (_isLoaded) return;
UpdatePath();
_isLoaded = true;
};
}
public AnimationPath() => Loaded += (s, e) => UpdatePath();
/// <summary>
/// 动画完成事件
@@ -213,15 +213,8 @@ namespace HandyControl.Controls
_panelPage.Children.Add(CreatePateButton());
}
if (index == -1)
{
if (count > 0)
{
var button = _panelPage.Children[0];
button.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent, button));
}
}
else if (index >= 0 && index < count)
if (index == -1 && count > 0) index = 0;
if (index >= 0 && index < count)
{
var button = _panelPage.Children[index];
button.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent, button));
@@ -109,7 +109,7 @@ namespace HandyControl.Controls
if (string.IsNullOrEmpty(token))
{
window = VisualHelper.GetActiveWindow();
window = WindowHelper.GetActiveWindow();
}
else
{
@@ -146,7 +146,7 @@ namespace HandyControl.Controls
{
if (string.IsNullOrEmpty(_token))
{
Close(VisualHelper.GetActiveWindow());
Close(WindowHelper.GetActiveWindow());
}
else if (WindowDic.TryGetValue(_token, out var window))
{
@@ -0,0 +1,82 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class Divider : Control
{
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);
}
}
}
@@ -0,0 +1,154 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Threading;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
{
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()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
public static Notification Show(object content, ShowAnimation showAnimation = ShowAnimation.None, bool staysOpen = false)
{
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;
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
if (_shouldBeClosed)
{
return;
}
var desktopWorkingArea = SystemParameters.WorkArea;
switch (ShowAnimation)
{
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;
}
}
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();
}
}
}
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using HandyControl.Data;
@@ -24,8 +25,6 @@ namespace HandyControl.Controls
private readonly int _id;
private static int NextId;
private ImageSource _icon;
private IntPtr _iconCurrentHandle;
@@ -56,6 +55,10 @@ namespace HandyControl.Controls
private bool _isDisposed;
private static int NextId;
private static readonly Dictionary<string, NotifyIcon> NotifyIconDic = new Dictionary<string, NotifyIcon>();
static NotifyIcon()
{
VisibilityProperty.OverrideMetadata(typeof(NotifyIcon), new PropertyMetadata(Visibility.Visible, OnVisibilityChanged));
@@ -111,6 +114,127 @@ namespace HandyControl.Controls
_dispatcherTimerPos.Tick += DispatcherTimerPos_Tick;
}
public static void Register(string token, NotifyIcon notifyIcon)
{
if (string.IsNullOrEmpty(token) || notifyIcon == null) return;
NotifyIconDic[token] = notifyIcon;
}
public static void Unregister(string token, NotifyIcon notifyIcon)
{
if (string.IsNullOrEmpty(token) || notifyIcon == null) return;
if (NotifyIconDic.ContainsKey(token))
{
if (ReferenceEquals(NotifyIconDic[token], notifyIcon))
{
NotifyIconDic.Remove(token);
}
}
}
public static void Unregister(NotifyIcon notifyIcon)
{
if (notifyIcon == null) return;
var first = NotifyIconDic.FirstOrDefault(item => ReferenceEquals(notifyIcon, item.Value));
if (!string.IsNullOrEmpty(first.Key))
{
NotifyIconDic.Remove(first.Key);
}
}
public static void Unregister(string token)
{
if (string.IsNullOrEmpty(token)) return;
if (NotifyIconDic.ContainsKey(token))
{
NotifyIconDic.Remove(token);
}
}
public static void ShowBalloonTip(string title, string content, NotifyIconInfoType infoType, string token)
{
if (NotifyIconDic.TryGetValue(token, out var notifyIcon))
{
notifyIcon.ShowBalloonTip(title, content, infoType);
}
}
public void ShowBalloonTip(string title, string content, NotifyIconInfoType infoType)
{
if (!_added || DesignerHelper.IsInDesignMode) return;
var data = new NOTIFYICONDATA
{
uFlags = NativeMethods.NIF_INFO,
hWnd = _messageWindowHandle,
uID = _id,
szInfoTitle = title ?? string.Empty,
szInfo = content ?? string.Empty
};
switch (infoType)
{
case NotifyIconInfoType.Info:
data.dwInfoFlags = NativeMethods.NIIF_INFO;
break;
case NotifyIconInfoType.Warning:
data.dwInfoFlags = NativeMethods.NIIF_WARNING;
break;
case NotifyIconInfoType.Error:
data.dwInfoFlags = NativeMethods.NIIF_ERROR;
break;
case NotifyIconInfoType.None:
data.dwInfoFlags = NativeMethods.NIIF_NONE;
break;
}
UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_MODIFY, data);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void CloseContextControl()
{
if (_contextContent != null)
{
_contextContent.IsOpen = false;
}
else if (ContextMenu != null)
{
ContextMenu.IsOpen = false;
}
}
public static readonly DependencyProperty TokenProperty = DependencyProperty.Register(
"Token", typeof(string), typeof(NotifyIcon), new PropertyMetadata(default(string), OnTokenChanged));
private static void OnTokenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is NotifyIcon notifyIcon)
{
if (e.NewValue == null)
{
Unregister(notifyIcon);
}
else
{
Register(e.NewValue.ToString(), notifyIcon);
}
}
}
public string Token
{
get => (string) GetValue(TokenProperty);
set => SetValue(TokenProperty, value);
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(NotifyIcon), new PropertyMetadata(default(string)));
@@ -190,6 +314,12 @@ namespace HandyControl.Controls
}
}
public bool IsBlink
{
get => (bool)GetValue(IsBlinkProperty);
set => SetValue(IsBlinkProperty, value);
}
private void DispatcherTimerBlinkTick(object sender, EventArgs e)
{
if (Visibility != Visibility.Visible || _iconCurrentHandle == IntPtr.Zero) return;
@@ -341,12 +471,6 @@ namespace HandyControl.Controls
return isFind;
}
public bool IsBlink
{
get => (bool) GetValue(IsBlinkProperty);
set => SetValue(IsBlinkProperty, value);
}
private void OnIconChanged()
{
if (_icon != null)
@@ -508,26 +632,14 @@ namespace HandyControl.Controls
Content = ContextContent
};
_contextContent.IsOpen = true;
var handle = IntPtr.Zero;
var hwndSource = (HwndSource)PresentationSource.FromVisual(_contextContent.Child);
if (hwndSource != null)
{
handle = hwndSource.Handle;
}
UnsafeNativeMethods.SetForegroundWindow(handle);
UnsafeNativeMethods.SetForegroundWindow(_contextContent.Child.GetHandle());
}
else if (ContextMenu != null)
{
ContextMenu.Placement = PlacementMode.Mouse;
ContextMenu.IsOpen = true;
var handle = IntPtr.Zero;
var hwndSource = (HwndSource)PresentationSource.FromVisual(ContextMenu);
if (hwndSource != null)
{
handle = hwndSource.Handle;
}
UnsafeNativeMethods.SetForegroundWindow(handle);
UnsafeNativeMethods.SetForegroundWindow(ContextMenu.GetHandle());
}
}
@@ -565,23 +677,5 @@ namespace HandyControl.Controls
_isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void CloseContextControl()
{
if (_contextContent != null)
{
_contextContent.IsOpen = false;
}
else if (ContextMenu != null)
{
ContextMenu.IsOpen = false;
}
}
}
}
@@ -0,0 +1,64 @@
using System.Windows;
using System.Windows.Input;
namespace HandyControl.Controls
{
public sealed class Sprite : System.Windows.Window
{
private bool _isLeftButtonPressed;
private double _leftMax;
private double _topMax;
private Sprite()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
InputManager.Current.PostProcessInput += Current_PostProcessInput;
}
private void Current_PostProcessInput(object sender, ProcessInputEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
_isLeftButtonPressed = true;
}
else if(_isLeftButtonPressed)
{
if (Left < 0)
{
Left = 0;
}
if (Left > _leftMax)
{
Left = _leftMax;
}
if (Top > _topMax)
{
Top = _topMax;
}
}
}
public static Sprite Show(object content)
{
var sprite = new Sprite
{
Content = content
};
sprite.Show();
var desktopWorkingArea = SystemParameters.WorkArea;
sprite._leftMax = desktopWorkingArea.Width - sprite.ActualWidth;
sprite._topMax = desktopWorkingArea.Height - sprite.ActualHeight;
sprite.Left = sprite._leftMax - 50;
sprite.Top = 50 - sprite.Padding.Top;
return sprite;
}
}
}
@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Tools;
@@ -14,7 +15,8 @@ namespace HandyControl.Controls
[TemplateVisualState(GroupName = PresentationGroup, Name = DefaultTransitionState)]
[TemplatePart(Name = PreviousContentPresentationSitePartName, Type = typeof(ContentControl))]
[TemplatePart(Name = CurrentContentPresentationSitePartName, Type = typeof(ContentControl))]
public class TransitioningContentControl : ContentControl
[ContentProperty("Content")]
public class TransitioningContentControl : Control
{
private Storyboard _currentTransition;
@@ -76,11 +78,28 @@ namespace HandyControl.Controls
VisualStateManager.GoToState(this, Transition, true);
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(object), typeof(TransitioningContentControl), new PropertyMetadata(default(object), OnContentChanged));
StartTransition(oldContent, newContent);
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TransitioningContentControl) d;
ctl.StartTransition(e.OldValue, e.NewValue);
}
public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register(
"ContentTemplate", typeof(DataTemplate), typeof(TransitioningContentControl), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ContentTemplate
{
get => (DataTemplate) GetValue(ContentTemplateProperty);
set => SetValue(ContentTemplateProperty, value);
}
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "newContent", Justification = "Should be used in the future.")]
@@ -35,18 +35,28 @@ namespace HandyControl.Controls
set => SetValue(OffsetAngleProperty, value);
}
// ReSharper disable once RedundantAssignment
protected override Size MeasureOverride(Size availableSize)
{
if (Children.Count == 0) return new Size(Diameter, Diameter);
availableSize = new Size(Diameter, Diameter);
var newSize = new Size(Diameter, Diameter);
foreach (UIElement element in Children)
{
element.Measure(newSize);
}
return newSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
var i = 0;
var perDeg = 360.0 / Children.Count;
var radius = Diameter / 2;
foreach (UIElement element in Children)
{
element.Measure(availableSize);
var centerX = element.DesiredSize.Width / 2.0;
var centerY = element.DesiredSize.Height / 2.0;
var angle = perDeg * i++ + OffsetAngle;
@@ -60,11 +70,12 @@ namespace HandyControl.Controls
var r = Math.PI * angle / 180.0;
var x = radius * Math.Cos(r);
var y = radius * Math.Sin(r);
var rectX = x + availableSize.Width / 2 - centerX;
var rectY = y + availableSize.Height / 2 - centerY;
var rectX = x + finalSize.Width / 2 - centerX;
var rectY = y + finalSize.Height / 2 - centerY;
element.Arrange(new Rect(rectX, rectY, element.DesiredSize.Width, element.DesiredSize.Height));
}
return availableSize;
return finalSize;
}
}
}
@@ -0,0 +1,166 @@
using System;
using System.Windows;
using System.Windows.Controls;
namespace HandyControl.Controls
{
public class HoneycombPanel : Panel
{
private double _unitLength;
private HoneycombStuffer _stuffer;
private static int GetXCount(int count)
{
if (count == 0) return 0;
count -= 1;
var index = (int) Math.Floor(Math.Pow((12.0 * count + 25) / 36, 0.5) - 5.0 / 6);
var valeIndex = 3 * index * index + 5 * index;
var centerValue = valeIndex + 2;
return count >= centerValue
? 4 * index + 6
: count > valeIndex
? 4 * index + 4
: 4 * index + 2;
}
private static int GetYCount(int count)
{
if (count == 0) return 0;
count -= 1;
var index = (int)Math.Floor(Math.Pow(count / 3.0 + 0.25, 0.5) - 0.5);
var valeIndex = 3 * index * index + 3 * index;
return count > valeIndex
? 2 * index + 2
: 2 * index;
}
/*
* layout order
*
* ● ●
* (7) (8)
*
* ● ● ●
* (6) (1) (9)
*
* ● ● ● ...
* (5) (0) (2)
*
* ● ● ...
* (4) (3)
*
*/
protected override Size MeasureOverride(Size availableSize)
{
var maxSize = new Size();
foreach (UIElement child in InternalChildren)
{
if (child != null)
{
child.Measure(availableSize);
maxSize.Width = Math.Max(maxSize.Width, child.DesiredSize.Width);
maxSize.Height = Math.Max(maxSize.Height, child.DesiredSize.Height);
}
}
_unitLength = Math.Max(maxSize.Width, maxSize.Height) / 2;
var xCount = GetXCount(InternalChildren.Count);
var yCount = GetYCount(InternalChildren.Count);
var availableWidth = xCount * _unitLength;
var availableHeight = yCount * Math.Pow(3, 0.5) * _unitLength + _unitLength * 2;
return new Size(availableWidth, availableHeight);
}
protected override Size ArrangeOverride(Size finalSize)
{
var childLength = _unitLength * 2;
_stuffer = new HoneycombStuffer(new Rect(finalSize.Width / 2 - _unitLength,
finalSize.Height / 2 - _unitLength, childLength, childLength));
foreach (UIElement child in InternalChildren)
{
child.Arrange(_stuffer.Move());
}
return finalSize;
}
private class HoneycombStuffer
{
private int _turns;
private int _maxIndex;
private int _currentIndex = -1;
private readonly double _offsetX;
private readonly double _offsetY;
private Rect _childBounds;
private readonly double[] _offsetXArr;
private readonly double[] _offsetYArr;
public HoneycombStuffer(Rect childBounds)
{
_childBounds = childBounds;
_offsetX = childBounds.Width / 2;
_offsetY = Math.Pow(3, 0.5) * _offsetX;
_offsetXArr = new[]
{
2 * _offsetX,
_offsetX,
-_offsetX,
-2 * _offsetX,
-_offsetX,
_offsetX
};
_offsetYArr = new[]
{
0,
_offsetY,
_offsetY,
0,
-_offsetY,
-_offsetY
};
}
public Rect Move()
{
_currentIndex++;
if (_currentIndex > _maxIndex)
{
_turns++;
_maxIndex = _turns * 6 - 1;
_currentIndex = 0;
_childBounds.Offset(_offsetX, -_offsetY);
return _childBounds;
}
if (_turns > 0)
{
var index = _currentIndex / _turns;
_childBounds.Offset(_offsetXArr[index], _offsetYArr[index]);
}
return _childBounds;
}
}
}
}
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
@@ -31,7 +32,15 @@ namespace HandyControl.Controls
"DefaultValue", typeof(double), typeof(Rate), new PropertyMetadata(ValueBoxes.Double0Box));
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(double), typeof(Rate), new PropertyMetadata(ValueBoxes.Double0Box));
"Value", typeof(double), typeof(Rate), new PropertyMetadata(ValueBoxes.Double0Box, OnValueChanged));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) =>
((Rate) d).OnValueChanged(new FunctionEventArgs<double>(ValueChangedEvent, d)
{
Info = (double)e.NewValue
});
protected virtual void OnValueChanged(FunctionEventArgs<double> e) => RaiseEvent(e);
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(Rate), new PropertyMetadata(default(string)));
@@ -44,6 +53,22 @@ namespace HandyControl.Controls
private bool _isLoaded;
private bool _updateItems;
#region Public Events
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble,
typeof(EventHandler<FunctionEventArgs<double>>), typeof(Rate));
public event EventHandler<FunctionEventArgs<double>> ValueChanged
{
add => AddHandler(ValueChangedEvent, value);
remove => RemoveHandler(ValueChangedEvent, value);
}
#endregion Public Events
public Rate()
{
AddHandler(RateItem.SelectedChangedEvent, new RoutedEventHandler(RateItemSelectedChanged));
@@ -52,8 +77,15 @@ namespace HandyControl.Controls
Loaded += (s, e) =>
{
if (DesignerHelper.IsInDesignMode) return;
_updateItems = false;
OnApplyTemplateInternal();
_updateItems = true;
UpdateItems();
if (_isLoaded) return;
_isLoaded = true;
if (Value <= 0)
{
if (DefaultValue > 0)
@@ -123,11 +155,8 @@ namespace HandyControl.Controls
set => SetValue(IsReadOnlyProperty, value);
}
private void RateItemValueChanged(object sender, RoutedEventArgs e)
{
Value =
(from RateItem item in Items where item.IsSelected select item.IsHalf ? 0.5 : 1).Sum();
}
private void RateItemValueChanged(object sender, RoutedEventArgs e) =>
Value = (from RateItem item in Items where item.IsSelected select item.IsHalf ? 0.5 : 1).Sum();
private void RateItemSelectedChanged(object sender, RoutedEventArgs e)
{
@@ -154,29 +183,32 @@ namespace HandyControl.Controls
}
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is RateItem;
}
protected override bool IsItemItsOwnContainerOverride(object item) => item is RateItem;
protected override DependencyObject GetContainerForItemOverride()
protected override DependencyObject GetContainerForItemOverride() => new RateItem();
private void OnApplyTemplateInternal()
{
return new RateItem();
Items.Clear();
for (var i = 1; i <= Count; i++)
{
var item = new RateItem
{
Index = i
};
Items.Add(item);
}
}
public override void OnApplyTemplate()
{
if (!_isLoaded)
{
Items.Clear();
for (var i = 1; i <= Count; i++)
{
Items.Add(new RateItem
{
Index = i
});
}
_updateItems = true;
OnApplyTemplateInternal();
_updateItems = false;
}
base.OnApplyTemplate();
@@ -191,7 +223,7 @@ namespace HandyControl.Controls
protected override void UpdateItems()
{
if (!_isLoaded) return;
if (!_isLoaded || !_updateItems) return;
var count = (int) Value;
for (var i = 0; i < count; i++)
@@ -224,9 +256,6 @@ namespace HandyControl.Controls
}
}
public void Reset()
{
Value = DefaultValue;
}
public void Reset() => Value = DefaultValue;
}
}
@@ -46,7 +46,13 @@ namespace HandyControl.Controls
public RateItem()
{
Loaded += (s, e) => _isLoaded = true;
Loaded += (s, e) =>
{
if (_isLoaded) return;
_isLoaded = true;
OnApplyTemplate();
};
}
public bool AllowClear
@@ -87,7 +93,7 @@ namespace HandyControl.Controls
if (_isHalf == value) return;
_isHalf = value;
if (_icon == null) return;
_icon.Width = value ? ActualWidth / 2 : ActualWidth;
_icon.Width = value ? Width / 2 : Width;
}
}
@@ -134,7 +140,7 @@ namespace HandyControl.Controls
if (IsReadOnly) return;
if (!AllowHalf) return;
var p = e.GetPosition(this);
IsHalf = p.X < ActualWidth / 2;
IsHalf = p.X < Width / 2;
}
public override void OnApplyTemplate()
@@ -147,7 +153,7 @@ namespace HandyControl.Controls
{
if (_icon == null) return;
_icon.Show(IsSelected);
_icon.Width = IsHalf ? ActualWidth / 2 : ActualWidth;
_icon.Width = IsHalf ? Width / 2 : Width;
}
}
@@ -202,7 +208,7 @@ namespace HandyControl.Controls
if (AllowHalf)
{
var p = e.GetPosition(this);
IsHalf = p.X < ActualWidth / 2;
IsHalf = p.X < Width / 2;
}
}
}
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
@@ -7,7 +8,7 @@ using HandyControl.Tools.Extension;
namespace HandyControl.Controls
{
public class SideMenuItem : HeaderedSimpleItemsControl, ISelectable
public class SideMenuItem : HeaderedSimpleItemsControl, ISelectable, ICommandSource
{
private bool _isMouseLeftButtonDown;
@@ -68,7 +69,22 @@ namespace HandyControl.Controls
}
}
protected virtual void OnSelected(RoutedEventArgs e) => RaiseEvent(e);
protected virtual void OnSelected(RoutedEventArgs e)
{
RaiseEvent(e);
switch (Command)
{
case null:
return;
case RoutedCommand command:
command.Execute(CommandParameter, CommandTarget);
break;
default:
Command.Execute(CommandParameter);
break;
}
}
public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble,
@@ -148,5 +164,54 @@ namespace HandyControl.Controls
ItemsHost.Show(isShow);
}
}
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command", typeof(ICommand), typeof(SideMenuItem), new PropertyMetadata(default(ICommand), OnCommandChanged));
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (SideMenuItem)d;
if (e.OldValue is ICommand oldCommand)
{
oldCommand.CanExecuteChanged -= ctl.CanExecuteChanged;
}
if (e.NewValue is ICommand newCommand)
{
newCommand.CanExecuteChanged += ctl.CanExecuteChanged;
}
}
public ICommand Command
{
get => (ICommand) GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter", typeof(object), typeof(SideMenuItem), new PropertyMetadata(default(object)));
public object CommandParameter
{
get => GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}
public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register(
"CommandTarget", typeof(IInputElement), typeof(SideMenuItem), new PropertyMetadata(default(IInputElement)));
public IInputElement CommandTarget
{
get => (IInputElement) GetValue(CommandTargetProperty);
set => SetValue(CommandTargetProperty, value);
}
private void CanExecuteChanged(object sender, EventArgs e)
{
if (Command == null) return;
IsEnabled = Command is RoutedCommand command
? command.CanExecute(CommandParameter, CommandTarget)
: Command.CanExecute(CommandParameter);
}
}
}
@@ -80,8 +80,14 @@ namespace HandyControl.Controls
/// <summary>
/// 是否显示关闭按钮
/// </summary>
public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.Register(
"ShowCloseButton", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));
public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.RegisterAttached(
"ShowCloseButton", typeof(bool), typeof(TabControl), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits));
public static void SetShowCloseButton(DependencyObject element, bool value)
=> element.SetValue(ShowCloseButtonProperty, value);
public static bool GetShowCloseButton(DependencyObject element)
=> (bool) element.GetValue(ShowCloseButtonProperty);
/// <summary>
/// 是否显示关闭按钮
@@ -92,6 +98,27 @@ namespace HandyControl.Controls
set => SetValue(ShowCloseButtonProperty, value);
}
/// <summary>
/// 是否显示上下文菜单
/// </summary>
public static readonly DependencyProperty ShowContextMenuProperty = DependencyProperty.RegisterAttached(
"ShowContextMenu", typeof(bool), typeof(TabControl), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.Inherits));
public static void SetShowContextMenu(DependencyObject element, bool value)
=> element.SetValue(ShowContextMenuProperty, value);
public static bool GetShowContextMenu(DependencyObject element)
=> (bool) element.GetValue(ShowContextMenuProperty);
/// <summary>
/// 是否显示上下文菜单
/// </summary>
public bool ShowContextMenu
{
get => (bool)GetValue(ShowContextMenuProperty);
set => SetValue(ShowContextMenuProperty, value);
}
/// <summary>
/// 是否将标签填充
/// </summary>
@@ -210,7 +237,7 @@ namespace HandyControl.Controls
}
if (IsEnableAnimation)
{
_headerPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
_headerPanel.SetCurrentValue(TabPanel.FluidMoveDurationProperty, new Duration(TimeSpan.FromMilliseconds(200)));
}
else
{
@@ -311,7 +338,7 @@ namespace HandyControl.Controls
Items.Insert(0, item);
if (IsEnableAnimation)
{
_headerPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
_headerPanel.SetCurrentValue(TabPanel.FluidMoveDurationProperty, new Duration(TimeSpan.FromMilliseconds(200)));
}
else
{
@@ -1,12 +1,14 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Interactivity;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
{
@@ -112,6 +114,91 @@ namespace HandyControl.Controls
}
}
/// <summary>
/// 是否显示关闭按钮
/// </summary>
public static readonly DependencyProperty ShowCloseButtonProperty =
TabControl.ShowCloseButtonProperty.AddOwner(typeof(TabItem));
/// <summary>
/// 是否显示关闭按钮
/// </summary>
public bool ShowCloseButton
{
get => (bool)GetValue(ShowCloseButtonProperty);
set => SetValue(ShowCloseButtonProperty, value);
}
public static void SetShowCloseButton(DependencyObject element, bool value)
=> element.SetValue(ShowCloseButtonProperty, value);
public static bool GetShowCloseButton(DependencyObject element)
=> (bool)element.GetValue(ShowCloseButtonProperty);
/// <summary>
/// 是否显示上下文菜单
/// </summary>
public static readonly DependencyProperty ShowContextMenuProperty =
TabControl.ShowContextMenuProperty.AddOwner(typeof(TabItem), new FrameworkPropertyMetadata(OnShowContextMenuChanged));
private static void OnShowContextMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TabItem) d;
if (ctl.Menu != null)
{
var show = (bool)e.NewValue;
ctl.Menu.IsEnabled = show;
ctl.Menu.Show(show);
}
}
/// <summary>
/// 是否显示上下文菜单
/// </summary>
public bool ShowContextMenu
{
get => (bool) GetValue(ShowContextMenuProperty);
set => SetValue(ShowContextMenuProperty, value);
}
public static void SetShowContextMenu(DependencyObject element, bool value)
=> element.SetValue(ShowContextMenuProperty, value);
public static bool GetShowContextMenu(DependencyObject element)
=> (bool)element.GetValue(ShowContextMenuProperty);
public static readonly DependencyProperty MenuProperty = DependencyProperty.Register(
"Menu", typeof(ContextMenu), typeof(TabItem), new PropertyMetadata(default(ContextMenu), OnMenuChanged));
private static void OnMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TabItem) d;
ctl.OnMenuChanged(e.NewValue as ContextMenu);
}
private void OnMenuChanged(ContextMenu menu)
{
if (IsLoaded && menu != null)
{
menu.DataContext = this;
menu.SetBinding(IsEnabledProperty, new Binding(ShowContextMenuProperty.Name)
{
Source = this
});
menu.SetBinding(VisibilityProperty, new Binding(ShowContextMenuProperty.Name)
{
Source = this,
Converter = ResourceHelper.GetResource<IValueConverter>("Boolean2VisibilityConverter")
});
}
}
public ContextMenu Menu
{
get => (ContextMenu) GetValue(MenuProperty);
set => SetValue(MenuProperty, value);
}
/// <summary>
/// 更新选项卡横向偏移
/// </summary>
@@ -135,6 +222,8 @@ namespace HandyControl.Controls
(s, e) => { TabControlParent.CloseAllItems(); }));
CommandBindings.Add(new CommandBinding(ControlCommands.CloseOther,
(s, e) => { TabControlParent.CloseOtherItems(this); }));
Loaded += (s, e) => OnMenuChanged(Menu);
}
private TabControl TabControlParent => new Lazy<TabControl>(() => ItemsControl.ItemsControlFromItemContainer(this) as TabControl).Value;
@@ -146,20 +235,28 @@ namespace HandyControl.Controls
Focus();
}
protected override void OnHeaderChanged(object oldHeader, object newHeader)
{
base.OnHeaderChanged(oldHeader, newHeader);
if (TabPanel != null)
{
TabPanel.ForceUpdate = true;
InvalidateMeasure();
TabPanel.ForceUpdate = true;
}
}
internal void Close()
{
var argsClosing = new CancelRoutedEventArgs(ClosingEvent, this);
RaiseEvent(argsClosing);
if (argsClosing.Cancel) return;
if (TabControlParent.IsEnableAnimation)
{
TabPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
}
else
{
TabPanel.FluidMoveDuration = new Duration(TimeSpan.FromSeconds(0));
}
TabPanel.SetCurrentValue(TabPanel.FluidMoveDurationProperty,
TabControlParent.IsEnableAnimation
? new Duration(TimeSpan.FromMilliseconds(200))
: new Duration(TimeSpan.FromMilliseconds(1)));
TabControlParent.IsInternalAction = true;
RaiseEvent(new RoutedEventArgs(ClosedEvent, this));
TabControlParent.Items.Remove(this);
@@ -1,5 +1,4 @@
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Tools;
@@ -18,18 +17,8 @@ namespace HandyControl.Controls
internal static void EnableBlur(Window window)
{
var accentPolicy = new ExternDllHelper.ACCENTPOLICY();
var accentPolicySize = Marshal.SizeOf(accentPolicy);
if (SystemVersionInfo >= SystemVersionInfo.Windows10_1809)
{
accentPolicy.AccentState = ExternDllHelper.ACCENTSTATE.ACCENT_ENABLE_ACRYLICBLURBEHIND;
}
else if (SystemVersionInfo >= SystemVersionInfo.Windows10)
{
accentPolicy.AccentState = ExternDllHelper.ACCENTSTATE.ACCENT_ENABLE_BLURBEHIND;
}
else
if (SystemVersionInfo < SystemVersionInfo.Windows10 ||
SystemVersionInfo >= SystemVersionInfo.Windows10_1903)
{
var colorValue = ResourceHelper.GetResource<uint>(ResourceToken.BlurGradientValue);
var color = ColorHelper.ToColor(colorValue);
@@ -38,6 +27,13 @@ namespace HandyControl.Controls
return;
}
var accentPolicy = new ExternDllHelper.ACCENTPOLICY();
var accentPolicySize = Marshal.SizeOf(accentPolicy);
accentPolicy.AccentState = SystemVersionInfo < SystemVersionInfo.Windows10_1809
? ExternDllHelper.ACCENTSTATE.ACCENT_ENABLE_BLURBEHIND
: ExternDllHelper.ACCENTSTATE.ACCENT_ENABLE_ACRYLICBLURBEHIND;
accentPolicy.AccentFlags = 2;
accentPolicy.GradientColor = ResourceHelper.GetResource<uint>(ResourceToken.BlurGradientValue);
@@ -51,7 +47,7 @@ namespace HandyControl.Controls
Data = accentPtr
};
ExternDllHelper.SetWindowCompositionAttribute(new WindowInteropHelper(window).Handle, ref data);
ExternDllHelper.SetWindowCompositionAttribute(window.GetHandle(), ref data);
Marshal.FreeHGlobal(accentPtr);
}
@@ -267,7 +267,7 @@ namespace HandyControl.Controls
MessageBox messageBox = null;
Application.Current.Dispatcher.Invoke(new Action(() =>
{
messageBox = CreateMessageBox(null, info.MessageBoxText, info.Caption, info.Button, MessageBoxImage.None, info.DefaultResult);
messageBox = CreateMessageBox(null, info.Message, info.Caption, info.Button, MessageBoxImage.None, info.DefaultResult);
SetButtonStatus(messageBox, info.Button);
if (!string.IsNullOrEmpty(info.IconKey))
@@ -277,9 +277,9 @@ namespace HandyControl.Controls
messageBox.ImageBrush = ResourceHelper.GetResource<Brush>(info.IconBrushKey);
}
if (info.Style != null)
if (info.StyleKey != null)
{
messageBox.Style = info.Style;
messageBox.Style = ResourceHelper.GetResource<Style>(info.StyleKey);
}
SystemSounds.Asterisk.Play();
messageBox.ShowDialog();
@@ -348,7 +348,7 @@ namespace HandyControl.Controls
throw new InvalidEnumArgumentException(nameof(defaultResult), (int)defaultResult, typeof(MessageBoxResult));
}
var ownerWindow = owner ?? VisualHelper.GetActiveWindow();
var ownerWindow = owner ?? WindowHelper.GetActiveWindow();
var ownerIsNull = ownerWindow is null;
return new MessageBox
@@ -8,5 +8,6 @@
Lg,
Xl,
Xxl,
Auto
}
}
@@ -0,0 +1,59 @@
namespace HandyControl.Data
{
public enum HatchStyle
{
Horizontal,
Vertical,
ForwardDiagonal,
BackwardDiagonal,
Cross,
DiagonalCross,
Percent05,
Percent10,
Percent20,
Percent25,
Percent30,
Percent40,
Percent50,
Percent60,
Percent70,
Percent75,
Percent80,
Percent90,
LightDownwardDiagonal,
LightUpwardDiagonal,
DarkDownwardDiagonal,
DarkUpwardDiagonal,
WideDownwardDiagonal,
WideUpwardDiagonal,
LightVertical,
LightHorizontal,
NarrowVertical,
NarrowHorizontal,
DarkVertical,
DarkHorizontal,
DashedDownwardDiagonal,
DashedUpwardDiagonal,
DashedHorizontal,
DashedVertical,
SmallConfetti,
LargeConfetti,
ZigZag,
Wave,
DiagonalBrick,
HorizontalBrick,
Weave,
Plaid,
Divot,
DottedGrid,
DottedDiamond,
Shingle,
Trellis,
Sphere,
SmallGrid,
SmallCheckerBoard,
LargeCheckerBoard,
OutlinedDiamond,
SolidDiamond
}
}
@@ -0,0 +1,8 @@
namespace HandyControl.Data.Enum
{
public enum MouseHitMode
{
Click,
Hover
}
}
@@ -0,0 +1,25 @@
namespace HandyControl.Data
{
public enum NotifyIconInfoType
{
/// <summary>
/// No Icon.
/// </summary>
None,
/// <summary>
/// A Information Icon.
/// </summary>
Info,
/// <summary>
/// A Warning Icon.
/// </summary>
Warning,
/// <summary>
/// A Error Icon.
/// </summary>
Error
}
}
@@ -0,0 +1,10 @@
namespace HandyControl.Data
{
public enum ShowAnimation
{
None,
HorizontalMove,
VerticalMove,
Fade
}
}
@@ -4,7 +4,7 @@ namespace HandyControl.Data
{
public class MessageBoxInfo
{
public string MessageBoxText { get; set; }
public string Message { get; set; }
public string Caption { get; set; }
@@ -16,6 +16,6 @@ namespace HandyControl.Data
public MessageBoxResult DefaultResult { get; set; } = MessageBoxResult.None;
public Style Style { get; set; }
public string StyleKey { get; set; }
}
}
@@ -8,8 +8,11 @@ namespace HandyControl.Data
public struct SystemVersionInfo
{
public static SystemVersionInfo Windows10 => new SystemVersionInfo(10, 0, 10240);
public static SystemVersionInfo Windows10_1809 => new SystemVersionInfo(10, 0, 17763);
public static SystemVersionInfo Windows10_1903 => new SystemVersionInfo(10, 0, 18362);
public SystemVersionInfo(int major, int minor, int build)
{
Major = major;
@@ -6,7 +6,7 @@
<SharedGUID>aac11083-faca-405d-9197-5c1212d65656</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>HandyControl_Shared</Import_RootNamespace>
<Import_RootNamespace>HandyControl</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\BackgroundSwitchElement.cs" />
@@ -19,18 +19,46 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\PanelElement.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\PasswordBoxAttach.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\RectangleAttach.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\TextBlockAttach.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\FloatingBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\SplitButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\GrowlWindow.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Image\ImageBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Divider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Magnifier.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ButtonGroup.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Card.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ToggleBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Notification.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Sprite.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\ToggleBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\HoneycombPanel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Slider\RangeSlider\RangeTrack.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Slider\RangeSlider\RangeThumb.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Slider\RangeSlider\TwoWayRangeBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\RunningBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\HatchStyle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\MouseHitMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\ShowAnimation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\NotifyIconInfoType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interactivity\Commands\CloseWindowCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interactivity\Commands\OpenLinkCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\DiscreteGeometryKeyFrame.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\EasingGeometryKeyFrame.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\GeometryAnimation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\GeometryAnimationBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\GeometryAnimationUsingKeyFrames.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\GeometryKeyFrame.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\GeometryKeyFrameCollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\LinearGeometryKeyFrame.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\ResolvedKeyFrameEntry.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\Animation\SplineGeometryKeyFrame.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\BorderCircularClipConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\ColLayoutConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\CornerRadiusSplitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Double2GridLengthConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Number2PercentageConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\RectangleCircularConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\ThicknessSplitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\FrameworkElementExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\StringExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\ValueExtension.cs" />
@@ -83,7 +111,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Dialog.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\GotoTop.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Gravatar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Growl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\Growl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\NotifyIcon.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Pagination.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ScrollViewer.cs" />
@@ -251,12 +279,12 @@
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\GeometryExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\UIElementExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\GifImageAnimator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\GithubGravatarGenerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Generator\GithubGravatarGenerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Generator\HatchBrushGenerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\AnimationHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ArithmeticHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ColorHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ConfigHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\CreateParams.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\DesignerHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\DpiHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ExternDllHelper.cs" />
@@ -264,10 +292,14 @@
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ResourceHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SecurityHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SingleOpenHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\TokenizerHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ValidateHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\VisualHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\WindowHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Hook\ClipboardHook.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Hook\KeyboardHook.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Hook\MouseHook.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Hook\SystemMenuHook.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\BitmapHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\BITMAPINFO.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\CommonHandles.cs" />
@@ -353,6 +385,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\DividerBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\CardBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -373,10 +409,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\RunningBlockBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\SliderBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\SplitButtonBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\ToggleBlockBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -389,6 +433,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Divider.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\FloatingBlock.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Growl.xaml">
<SubType>Designer</SubType>
<Generator>XamlIntelliSenseFileGenerator</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Menu.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -677,6 +733,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Notification.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\NumericUpDown.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -725,6 +785,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\RunningBlock.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\ScrollViewer.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -749,6 +813,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\SplitButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Sprite.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\StepBar.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -814,4 +886,14 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)Controls\Growl\" />
<Folder Include="$(MSBuildThisFileDirectory)Tools\Generator\" />
</ItemGroup>
<ItemGroup>
<Page Update="E:\Work\GitHub\HandyControl\src\Shared\HandyControl_Shared\Themes\Styles\Base\SplitButtonBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>
@@ -0,0 +1,24 @@
using System;
using System.Windows;
using System.Windows.Input;
namespace HandyControl.Interactivity
{
public class CloseWindowCommand : ICommand
{
public bool CanExecute(object parameter) => true;
public void Execute(object parameter)
{
if (parameter is DependencyObject dependencyObject)
{
if (Window.GetWindow(dependencyObject) is Window window)
{
window.Close();
}
}
}
public event EventHandler CanExecuteChanged;
}
}
@@ -156,5 +156,10 @@ namespace HandyControl.Interactivity
/// 前置主窗口
/// </summary>
public static PushMainWindow2TopCommand PushMainWindow2Top { get; } = new PushMainWindow2TopCommand();
/// <summary>
/// 关闭窗口
/// </summary>
public static CloseWindowCommand CloseWindow { get; } = new CloseWindowCommand();
}
}
@@ -0,0 +1,25 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace HandyControl.Media.Animation
{
public class DiscreteGeometryKeyFrame : GeometryKeyFrame
{
public DiscreteGeometryKeyFrame()
{
}
public DiscreteGeometryKeyFrame(Geometry value) : base(value)
{
}
public DiscreteGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
{
}
protected override Freezable CreateInstanceCore() => new DiscreteGeometryKeyFrame();
protected override double[] InterpolateValueCore(double[] baseValue, double keyFrameProgress) => keyFrameProgress < 1.0 ? baseValue : Numbers;
}
}
@@ -0,0 +1,63 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Expression.Drawing;
using HandyControl.Tools;
namespace HandyControl.Media.Animation
{
public class EasingGeometryKeyFrame : GeometryKeyFrame
{
public EasingGeometryKeyFrame()
{
}
public EasingGeometryKeyFrame(Geometry value) : base(value)
{
}
public EasingGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
{
}
public EasingGeometryKeyFrame(Geometry value, KeyTime keyTime, IEasingFunction easingFunction) : base(value, keyTime)
{
EasingFunction = easingFunction;
}
protected override Freezable CreateInstanceCore() => new EasingGeometryKeyFrame();
protected override double[] InterpolateValueCore(double[] baseValue, double keyFrameProgress)
{
var easingFunction = EasingFunction;
if (easingFunction != null)
{
keyFrameProgress = easingFunction.Ease(keyFrameProgress);
}
if (MathHelper.IsVerySmall(keyFrameProgress))
{
return baseValue;
}
if (MathHelper.AreClose(keyFrameProgress, 1))
{
return Numbers;
}
return AnimationHelper.InterpolateGeometryValue(baseValue, Numbers, keyFrameProgress);
}
public static readonly DependencyProperty EasingFunctionProperty = DependencyProperty.Register(
"EasingFunction", typeof(IEasingFunction), typeof(EasingGeometryKeyFrame), new PropertyMetadata(default(IEasingFunction)));
public IEasingFunction EasingFunction
{
get => (IEasingFunction) GetValue(EasingFunctionProperty);
set => SetValue(EasingFunctionProperty, value);
}
}
}
@@ -0,0 +1,179 @@
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Tools;
// ReSharper disable PossibleInvalidOperationException
namespace HandyControl.Media.Animation
{
public class GeometryAnimation : GeometryAnimationBase
{
private string[] _strings;
private double[] _numbersFrom;
private double[] _numbersTo;
private double[] _numbersAccumulator;
public GeometryAnimation()
{
}
public GeometryAnimation(string fromValue, string toValue) : this()
{
From = Geometry.Parse(fromValue);
To = Geometry.Parse(toValue);
}
private void UpdateValue()
{
if (_numbersFrom == null || _numbersTo == null || _numbersFrom.Length != _numbersTo.Length) return;
_numbersAccumulator = new double[_numbersFrom.Length];
for (var i = 0; i < _numbersFrom.Length; i++)
{
_numbersAccumulator[i] = _numbersTo[i] - _numbersFrom[i];
}
}
public GeometryAnimation(Geometry fromValue, Geometry toValue) : this()
{
From = fromValue;
To = toValue;
}
public GeometryAnimation(Geometry fromValue, Geometry toValue, Duration duration) : this()
{
From = fromValue;
To = toValue;
Duration = duration;
}
public GeometryAnimation(Geometry fromValue, Geometry toValue, Duration duration, FillBehavior fillBehavior) : this()
{
From = fromValue;
To = toValue;
Duration = duration;
FillBehavior = fillBehavior;
}
public new GeometryAnimation Clone() => (GeometryAnimation)base.Clone();
protected override Freezable CreateInstanceCore() => new GeometryAnimation();
protected override Geometry GetCurrentValueCore(Geometry defaultOriginValue, Geometry defaultDestinationValue, AnimationClock animationClock)
{
if (_numbersAccumulator == null)
{
if (_numbersFrom == null)
{
var geometryStr = defaultOriginValue.ToString(CultureInfo.InvariantCulture);
AnimationHelper.DecomposeGeometryStr(geometryStr, out _numbersFrom);
}
if (_numbersTo == null)
{
var geometryStr = defaultDestinationValue.ToString(CultureInfo.InvariantCulture);
AnimationHelper.DecomposeGeometryStr(geometryStr, out _numbersTo);
_strings = Regex.Split(geometryStr, RegularPatterns.DigitsPattern);
}
UpdateValue();
}
if (_numbersAccumulator == null) return defaultOriginValue;
var progress = animationClock.CurrentProgress.Value;
var easingFunction = EasingFunction;
if (easingFunction != null)
{
progress = easingFunction.Ease(progress);
}
var accumulated = new double[_numbersAccumulator.Length];
if (IsCumulative)
{
var currentRepeat = (double)(animationClock.CurrentIteration - 1);
if (currentRepeat > 0.0)
{
accumulated = new double[_numbersAccumulator.Length];
for (var i = 0; i < _numbersAccumulator.Length; i++)
{
accumulated[i] = _numbersAccumulator[i] * currentRepeat;
}
}
}
var numbers = new double[_numbersAccumulator.Length];
for (var i = 0; i < _numbersAccumulator.Length; i++)
{
numbers[i] = accumulated[i] + _numbersFrom[i] + _numbersAccumulator[i] * progress;
}
return AnimationHelper.ComposeGeometry(_strings, numbers);
}
public static readonly DependencyProperty FromProperty = DependencyProperty.Register(
"From", typeof(Geometry), typeof(GeometryAnimation), new PropertyMetadata(default(Geometry), OnFromChanged));
private static void OnFromChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (GeometryAnimation) d;
if (e.NewValue is Geometry geometry)
{
AnimationHelper.DecomposeGeometryStr(geometry.ToString(CultureInfo.InvariantCulture), out obj._numbersFrom);
obj.UpdateValue();
}
}
public Geometry From
{
get => (Geometry)GetValue(FromProperty);
set => SetValue(FromProperty, value);
}
public static readonly DependencyProperty ToProperty = DependencyProperty.Register(
"To", typeof(Geometry), typeof(GeometryAnimation), new PropertyMetadata(default(Geometry), OnToChanged));
private static void OnToChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (GeometryAnimation)d;
if (e.NewValue is Geometry geometry)
{
var geometryStr = geometry.ToString(CultureInfo.InvariantCulture);
AnimationHelper.DecomposeGeometryStr(geometryStr, out obj._numbersTo);
obj._strings = Regex.Split(geometryStr, RegularPatterns.DigitsPattern);
obj.UpdateValue();
}
}
public Geometry To
{
get => (Geometry)GetValue(ToProperty);
set => SetValue(ToProperty, value);
}
public static readonly DependencyProperty EasingFunctionProperty = DependencyProperty.Register(
"EasingFunction", typeof(IEasingFunction), typeof(GeometryAnimation), new PropertyMetadata(default(IEasingFunction)));
public IEasingFunction EasingFunction
{
get => (IEasingFunction)GetValue(EasingFunctionProperty);
set => SetValue(EasingFunctionProperty, value);
}
public bool IsCumulative
{
get => (bool)GetValue(IsCumulativeProperty);
set => SetValue(IsCumulativeProperty, value);
}
}
}
@@ -0,0 +1,53 @@
using System;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace HandyControl.Media.Animation
{
public abstract class GeometryAnimationBase : AnimationTimeline
{
public new GeometryAnimationBase Clone() => (GeometryAnimationBase)base.Clone();
public sealed override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
{
if (defaultOriginValue == null)
{
throw new ArgumentNullException(nameof(defaultOriginValue));
}
if (defaultDestinationValue == null)
{
throw new ArgumentNullException(nameof(defaultDestinationValue));
}
return GetCurrentValue((Geometry)defaultOriginValue, (Geometry)defaultDestinationValue, animationClock);
}
public override Type TargetPropertyType
{
get
{
ReadPreamble();
return typeof(Geometry);
}
}
public Geometry GetCurrentValue(Geometry defaultOriginValue, Geometry defaultDestinationValue, AnimationClock animationClock)
{
ReadPreamble();
if (animationClock == null)
{
throw new ArgumentNullException(nameof(animationClock));
}
if (animationClock.CurrentState == ClockState.Stopped)
{
return defaultDestinationValue;
}
return GetCurrentValueCore(defaultOriginValue, defaultDestinationValue, animationClock);
}
protected abstract Geometry GetCurrentValueCore(Geometry defaultOriginValue, Geometry defaultDestinationValue, AnimationClock animationClock);
}
}
@@ -0,0 +1,519 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Tools;
// ReSharper disable PossibleInvalidOperationException
namespace HandyControl.Media.Animation
{
[ContentProperty("KeyFrames")]
public class GeometryAnimationUsingKeyFrames : GeometryAnimationBase, IKeyFrameAnimation, IAddChild
{
private string[] _strings;
public string[] Strings
{
get
{
if (_keyFrames == null || _keyFrames.Count == 0)
{
return null;
}
return _strings ??= Regex.Split(_keyFrames[0].Value.ToString(CultureInfo.InvariantCulture), RegularPatterns.DigitsPattern);
}
}
private GeometryKeyFrameCollection _keyFrames;
private ResolvedKeyFrameEntry[] _sortedResolvedKeyFrames;
private bool _areKeyTimesValid;
public GeometryAnimationUsingKeyFrames() => _areKeyTimesValid = true;
public new GeometryAnimationUsingKeyFrames Clone() => (GeometryAnimationUsingKeyFrames)base.Clone();
public new GeometryAnimationUsingKeyFrames CloneCurrentValue() => (GeometryAnimationUsingKeyFrames)base.CloneCurrentValue();
protected override bool FreezeCore(bool isChecking)
{
var canFreeze = base.FreezeCore(isChecking);
canFreeze &= Freeze(_keyFrames, isChecking);
if (canFreeze & !_areKeyTimesValid)
{
ResolveKeyTimes();
}
return canFreeze;
}
protected override void OnChanged()
{
_areKeyTimesValid = false;
base.OnChanged();
}
protected override Freezable CreateInstanceCore() => new GeometryAnimationUsingKeyFrames();
protected override void CloneCore(Freezable sourceFreezable)
{
var sourceAnimation = (GeometryAnimationUsingKeyFrames)sourceFreezable;
base.CloneCore(sourceFreezable);
CopyCommon(sourceAnimation, false);
}
protected override void CloneCurrentValueCore(Freezable sourceFreezable)
{
var sourceAnimation = (GeometryAnimationUsingKeyFrames)sourceFreezable;
base.CloneCurrentValueCore(sourceFreezable);
CopyCommon(sourceAnimation, true);
}
protected override void GetAsFrozenCore(Freezable source)
{
var sourceAnimation = (GeometryAnimationUsingKeyFrames)source;
base.GetAsFrozenCore(source);
CopyCommon(sourceAnimation, false);
}
protected override void GetCurrentValueAsFrozenCore(Freezable source)
{
var sourceAnimation = (GeometryAnimationUsingKeyFrames)source;
base.GetCurrentValueAsFrozenCore(source);
CopyCommon(sourceAnimation, true);
}
private void CopyCommon(GeometryAnimationUsingKeyFrames sourceAnimation, bool isCurrentValueClone)
{
_areKeyTimesValid = sourceAnimation._areKeyTimesValid;
if (_areKeyTimesValid && sourceAnimation._sortedResolvedKeyFrames != null)
{
_sortedResolvedKeyFrames = (ResolvedKeyFrameEntry[])sourceAnimation._sortedResolvedKeyFrames.Clone();
}
if (sourceAnimation._keyFrames != null)
{
if (isCurrentValueClone)
{
_keyFrames = (GeometryKeyFrameCollection)sourceAnimation._keyFrames.CloneCurrentValue();
}
else
{
_keyFrames = sourceAnimation._keyFrames.Clone();
}
OnFreezablePropertyChanged(null, _keyFrames);
}
}
void IAddChild.AddChild(object child)
{
WritePreamble();
if (child == null)
{
throw new ArgumentNullException(nameof(child));
}
AddChild(child);
WritePostscript();
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void AddChild(object child)
{
if (child is GeometryKeyFrame keyFrame)
{
KeyFrames.Add(keyFrame);
}
else
{
throw new ArgumentException("Animation_ChildMustBeKeyFrame", nameof(child));
}
}
void IAddChild.AddText(string childText)
{
if (childText == null)
{
throw new ArgumentNullException(nameof(childText));
}
AddText(childText);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void AddText(string childText) => throw new InvalidOperationException("Animation_NoTextChildren");
protected override Geometry GetCurrentValueCore(Geometry defaultOriginValue, Geometry defaultDestinationValue, AnimationClock animationClock)
{
if (_keyFrames == null)
{
return defaultDestinationValue;
}
if (!_areKeyTimesValid)
{
ResolveKeyTimes();
}
if (_sortedResolvedKeyFrames == null)
{
return defaultDestinationValue;
}
var currentTime = animationClock.CurrentTime.Value;
var keyFrameCount = _sortedResolvedKeyFrames.Length;
var maxKeyFrameIndex = keyFrameCount - 1;
double[] currentIterationValue;
var currentResolvedKeyFrameIndex = 0;
while (currentResolvedKeyFrameIndex < keyFrameCount && currentTime > _sortedResolvedKeyFrames[currentResolvedKeyFrameIndex]._resolvedKeyTime)
{
currentResolvedKeyFrameIndex++;
}
while (currentResolvedKeyFrameIndex < maxKeyFrameIndex && currentTime == _sortedResolvedKeyFrames[currentResolvedKeyFrameIndex + 1]._resolvedKeyTime)
{
currentResolvedKeyFrameIndex++;
}
if (currentResolvedKeyFrameIndex == keyFrameCount)
{
currentIterationValue = GetResolvedKeyFrameValue(maxKeyFrameIndex);
}
else if (currentTime == _sortedResolvedKeyFrames[currentResolvedKeyFrameIndex]._resolvedKeyTime)
{
currentIterationValue = GetResolvedKeyFrameValue(currentResolvedKeyFrameIndex);
}
else
{
double currentSegmentProgress;
double[] fromValue;
if (currentResolvedKeyFrameIndex == 0)
{
AnimationHelper.DecomposeGeometryStr(defaultOriginValue.ToString(CultureInfo.InvariantCulture), out fromValue);
currentSegmentProgress = currentTime.TotalMilliseconds / _sortedResolvedKeyFrames[0]._resolvedKeyTime.TotalMilliseconds;
}
else
{
var previousResolvedKeyFrameIndex = currentResolvedKeyFrameIndex - 1;
var previousResolvedKeyTime = _sortedResolvedKeyFrames[previousResolvedKeyFrameIndex]._resolvedKeyTime;
fromValue = GetResolvedKeyFrameValue(previousResolvedKeyFrameIndex);
var segmentCurrentTime = currentTime - previousResolvedKeyTime;
var segmentDuration = _sortedResolvedKeyFrames[currentResolvedKeyFrameIndex]._resolvedKeyTime - previousResolvedKeyTime;
currentSegmentProgress = segmentCurrentTime.TotalMilliseconds / segmentDuration.TotalMilliseconds;
}
currentIterationValue = GetResolvedKeyFrame(currentResolvedKeyFrameIndex).InterpolateValue(fromValue, currentSegmentProgress);
}
return AnimationHelper.ComposeGeometry(Strings, currentIterationValue);
}
protected sealed override Duration GetNaturalDurationCore(Clock clock) => new Duration(LargestTimeSpanKeyTime);
IList IKeyFrameAnimation.KeyFrames
{
get => KeyFrames;
set => KeyFrames = (GeometryKeyFrameCollection)value;
}
public GeometryKeyFrameCollection KeyFrames
{
get
{
ReadPreamble();
if (_keyFrames == null)
{
if (IsFrozen)
{
_keyFrames = GeometryKeyFrameCollection.Empty;
}
else
{
WritePreamble();
_keyFrames = new GeometryKeyFrameCollection();
OnFreezablePropertyChanged(null, _keyFrames);
WritePostscript();
}
}
return _keyFrames;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
WritePreamble();
if (value != _keyFrames)
{
OnFreezablePropertyChanged(_keyFrames, value);
_keyFrames = value;
WritePostscript();
}
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeKeyFrames()
{
ReadPreamble();
return _keyFrames != null && _keyFrames.Count > 0;
}
private struct KeyTimeBlock
{
public int BeginIndex;
public int EndIndex;
}
private double[] GetResolvedKeyFrameValue(int resolvedKeyFrameIndex) =>
GetResolvedKeyFrame(resolvedKeyFrameIndex).Numbers;
private GeometryKeyFrame GetResolvedKeyFrame(int resolvedKeyFrameIndex) =>
_keyFrames[_sortedResolvedKeyFrames[resolvedKeyFrameIndex]._originalKeyFrameIndex];
private TimeSpan LargestTimeSpanKeyTime
{
get
{
var hasTimeSpanKeyTime = false;
var largestTimeSpanKeyTime = TimeSpan.Zero;
if (_keyFrames != null)
{
var keyFrameCount = _keyFrames.Count;
for (var index = 0; index < keyFrameCount; index++)
{
var keyTime = _keyFrames[index].KeyTime;
if (keyTime.Type == KeyTimeType.TimeSpan)
{
hasTimeSpanKeyTime = true;
if (keyTime.TimeSpan > largestTimeSpanKeyTime)
{
largestTimeSpanKeyTime = keyTime.TimeSpan;
}
}
}
}
return hasTimeSpanKeyTime ? largestTimeSpanKeyTime : TimeSpan.FromSeconds(1.0);
}
}
private void ResolveKeyTimes()
{
var keyFrameCount = 0;
if (_keyFrames != null)
{
keyFrameCount = _keyFrames.Count;
}
if (keyFrameCount == 0)
{
_sortedResolvedKeyFrames = null;
_areKeyTimesValid = true;
return;
}
_sortedResolvedKeyFrames = new ResolvedKeyFrameEntry[keyFrameCount];
var index = 0;
for (; index < keyFrameCount; index++)
{
_sortedResolvedKeyFrames[index]._originalKeyFrameIndex = index;
}
var duration = Duration;
var calculationDuration = duration.HasTimeSpan ? duration.TimeSpan : LargestTimeSpanKeyTime;
var maxKeyFrameIndex = keyFrameCount - 1;
var unspecifiedBlocks = new List<KeyTimeBlock>();
var hasPacedKeyTimes = false;
index = 0;
while (index < keyFrameCount)
{
// ReSharper disable once PossibleNullReferenceException
var keyTime = _keyFrames[index].KeyTime;
switch (keyTime.Type)
{
case KeyTimeType.Percent:
_sortedResolvedKeyFrames[index]._resolvedKeyTime = TimeSpan.FromMilliseconds(keyTime.Percent * calculationDuration.TotalMilliseconds);
index++;
break;
case KeyTimeType.TimeSpan:
_sortedResolvedKeyFrames[index]._resolvedKeyTime = keyTime.TimeSpan;
index++;
break;
case KeyTimeType.Paced:
case KeyTimeType.Uniform:
if (index == maxKeyFrameIndex)
{
_sortedResolvedKeyFrames[index]._resolvedKeyTime = calculationDuration;
index++;
}
else if (index == 0 && keyTime.Type == KeyTimeType.Paced)
{
_sortedResolvedKeyFrames[index]._resolvedKeyTime = TimeSpan.Zero;
index++;
}
else
{
if (keyTime.Type == KeyTimeType.Paced)
{
hasPacedKeyTimes = true;
}
var block = new KeyTimeBlock
{
BeginIndex = index
};
while (++index < maxKeyFrameIndex)
{
var type = _keyFrames[index].KeyTime.Type;
if (type == KeyTimeType.Percent || type == KeyTimeType.TimeSpan)
{
break;
}
if (type == KeyTimeType.Paced)
{
hasPacedKeyTimes = true;
}
}
block.EndIndex = index;
unspecifiedBlocks.Add(block);
}
break;
}
}
foreach (var block in unspecifiedBlocks)
{
var blockBeginTime = TimeSpan.Zero;
if (block.BeginIndex > 0)
{
blockBeginTime = _sortedResolvedKeyFrames[block.BeginIndex - 1]._resolvedKeyTime;
}
long segmentCount = block.EndIndex - block.BeginIndex + 1;
var uniformTimeStep = TimeSpan.FromTicks((_sortedResolvedKeyFrames[block.EndIndex]._resolvedKeyTime - blockBeginTime).Ticks / segmentCount);
index = block.BeginIndex;
var resolvedTime = blockBeginTime + uniformTimeStep;
while (index < block.EndIndex)
{
_sortedResolvedKeyFrames[index]._resolvedKeyTime = resolvedTime;
resolvedTime += uniformTimeStep;
index++;
}
}
if (hasPacedKeyTimes)
{
ResolvePacedKeyTimes();
}
Array.Sort(_sortedResolvedKeyFrames);
_areKeyTimesValid = true;
}
private void ResolvePacedKeyTimes()
{
var index = 1;
var maxKeyFrameIndex = _sortedResolvedKeyFrames.Length - 1;
do
{
if (_keyFrames[index].KeyTime.Type == KeyTimeType.Paced)
{
var firstPacedBlockKeyFrameIndex = index;
var segmentLengths = new List<double>();
var prePacedBlockKeyTime = _sortedResolvedKeyFrames[index - 1]._resolvedKeyTime;
var totalLength = 0.0;
var prevKeyValue = _keyFrames[index - 1].Numbers;
do
{
var currentKeyValue = _keyFrames[index].Numbers;
totalLength += Math.Abs(currentKeyValue[0] - prevKeyValue[0]);
segmentLengths.Add(totalLength);
prevKeyValue = currentKeyValue;
index++;
}
while (index < maxKeyFrameIndex && _keyFrames[index].KeyTime.Type == KeyTimeType.Paced);
totalLength += Math.Abs(_keyFrames[index].Numbers[0] - prevKeyValue[0]);
var pacedBlockDuration = _sortedResolvedKeyFrames[index]._resolvedKeyTime - prePacedBlockKeyTime;
for (int i = 0, currentKeyFrameIndex = firstPacedBlockKeyFrameIndex; i < segmentLengths.Count; i++, currentKeyFrameIndex++)
{
_sortedResolvedKeyFrames[currentKeyFrameIndex]._resolvedKeyTime = prePacedBlockKeyTime + TimeSpan.FromMilliseconds(segmentLengths[i] / totalLength * pacedBlockDuration.TotalMilliseconds);
}
}
else
{
index++;
}
}
while (index < maxKeyFrameIndex);
}
}
}
@@ -0,0 +1,69 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Tools;
public abstract class GeometryKeyFrame : Freezable, IKeyFrame
{
internal double[] Numbers;
protected GeometryKeyFrame()
{
}
protected GeometryKeyFrame(Geometry value)
{
AnimationHelper.DecomposeGeometryStr(value.ToString(CultureInfo.InvariantCulture), out var arr);
Numbers = arr;
Value = value;
}
protected GeometryKeyFrame(Geometry value, KeyTime keyTime) : this(value) => KeyTime = keyTime;
public static readonly DependencyProperty KeyTimeProperty = DependencyProperty.Register(
"KeyTime", typeof(KeyTime), typeof(GeometryKeyFrame), new PropertyMetadata(KeyTime.Uniform));
public KeyTime KeyTime
{
get => (KeyTime) GetValue(KeyTimeProperty);
set => SetValue(KeyTimeProperty, value);
}
object IKeyFrame.Value
{
get => Value;
set => Value = (Geometry)value;
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(Geometry), typeof(GeometryKeyFrame), new PropertyMetadata(default(Geometry), OnValueChanged));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (GeometryKeyFrame) d;
var v = (Geometry) e.NewValue;
AnimationHelper.DecomposeGeometryStr(v.ToString(CultureInfo.InvariantCulture), out var arr);
obj.Numbers = arr;
}
public Geometry Value
{
get => (Geometry) GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public double[] InterpolateValue(double[] baseValue, double keyFrameProgress)
{
if (keyFrameProgress < 0.0 || keyFrameProgress > 1.0)
{
throw new ArgumentOutOfRangeException(nameof(keyFrameProgress));
}
return InterpolateValueCore(baseValue, keyFrameProgress);
}
protected abstract double[] InterpolateValueCore(double[] baseValue, double keyFrameProgress);
}
@@ -0,0 +1,323 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
namespace HandyControl.Media.Animation
{
public class GeometryKeyFrameCollection : Freezable, IList
{
private List<GeometryKeyFrame> _keyFrames;
private static GeometryKeyFrameCollection s_emptyCollection;
public GeometryKeyFrameCollection()
{
_keyFrames = new List<GeometryKeyFrame>(2);
}
public static GeometryKeyFrameCollection Empty
{
get
{
if (s_emptyCollection == null)
{
var emptyCollection = new GeometryKeyFrameCollection
{
_keyFrames = new List<GeometryKeyFrame>(0)
};
emptyCollection.Freeze();
s_emptyCollection = emptyCollection;
}
return s_emptyCollection;
}
}
public new GeometryKeyFrameCollection Clone() => (GeometryKeyFrameCollection)base.Clone();
protected override Freezable CreateInstanceCore() => new GeometryKeyFrameCollection();
protected override void CloneCore(Freezable sourceFreezable)
{
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
base.CloneCore(sourceFreezable);
var count = sourceCollection._keyFrames.Count;
_keyFrames = new List<GeometryKeyFrame>(count);
for (var i = 0; i < count; i++)
{
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].Clone();
_keyFrames.Add(keyFrame);
OnFreezablePropertyChanged(null, keyFrame);
}
}
protected override void CloneCurrentValueCore(Freezable sourceFreezable)
{
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
base.CloneCurrentValueCore(sourceFreezable);
var count = sourceCollection._keyFrames.Count;
_keyFrames = new List<GeometryKeyFrame>(count);
for (var i = 0; i < count; i++)
{
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].CloneCurrentValue();
_keyFrames.Add(keyFrame);
OnFreezablePropertyChanged(null, keyFrame);
}
}
protected override void GetAsFrozenCore(Freezable sourceFreezable)
{
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
base.GetAsFrozenCore(sourceFreezable);
var count = sourceCollection._keyFrames.Count;
_keyFrames = new List<GeometryKeyFrame>(count);
for (var i = 0; i < count; i++)
{
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].GetAsFrozen();
_keyFrames.Add(keyFrame);
OnFreezablePropertyChanged(null, keyFrame);
}
}
protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
{
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
base.GetCurrentValueAsFrozenCore(sourceFreezable);
var count = sourceCollection._keyFrames.Count;
_keyFrames = new List<GeometryKeyFrame>(count);
for (var i = 0; i < count; i++)
{
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].GetCurrentValueAsFrozen();
_keyFrames.Add(keyFrame);
OnFreezablePropertyChanged(null, keyFrame);
}
}
protected override bool FreezeCore(bool isChecking)
{
var canFreeze = base.FreezeCore(isChecking);
for (var i = 0; i < _keyFrames.Count && canFreeze; i++)
{
canFreeze &= Freeze(_keyFrames[i], isChecking);
}
return canFreeze;
}
public IEnumerator GetEnumerator()
{
ReadPreamble();
return _keyFrames.GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
ReadPreamble();
((ICollection)_keyFrames).CopyTo(array, index);
}
public void CopyTo(GeometryKeyFrame[] array, int index)
{
ReadPreamble();
_keyFrames.CopyTo(array, index);
}
public int Count
{
get
{
ReadPreamble();
return _keyFrames.Count;
}
}
public object SyncRoot
{
get
{
ReadPreamble();
return ((ICollection)_keyFrames).SyncRoot;
}
}
public bool IsSynchronized
{
get
{
ReadPreamble();
return IsFrozen || Dispatcher != null;
}
}
int IList.Add(object keyFrame) => Add((GeometryKeyFrame)keyFrame);
public int Add(GeometryKeyFrame keyFrame)
{
if (keyFrame == null)
{
throw new ArgumentNullException(nameof(keyFrame));
}
WritePreamble();
OnFreezablePropertyChanged(null, keyFrame);
_keyFrames.Add(keyFrame);
WritePostscript();
return _keyFrames.Count - 1;
}
public void Clear()
{
WritePreamble();
if (_keyFrames.Count <= 0) return;
foreach (var frame in _keyFrames)
{
OnFreezablePropertyChanged(frame, null);
}
_keyFrames.Clear();
WritePostscript();
}
bool IList.Contains(object keyFrame) => Contains((GeometryKeyFrame)keyFrame);
public bool Contains(GeometryKeyFrame keyFrame)
{
ReadPreamble();
return _keyFrames.Contains(keyFrame);
}
int IList.IndexOf(object keyFrame) => IndexOf((GeometryKeyFrame)keyFrame);
public int IndexOf(GeometryKeyFrame keyFrame)
{
ReadPreamble();
return _keyFrames.IndexOf(keyFrame);
}
void IList.Insert(int index, object keyFrame) => Insert(index, (GeometryKeyFrame)keyFrame);
public void Insert(int index, GeometryKeyFrame keyFrame)
{
if (keyFrame == null)
{
throw new ArgumentNullException(nameof(keyFrame));
}
WritePreamble();
OnFreezablePropertyChanged(null, keyFrame);
_keyFrames.Insert(index, keyFrame);
WritePostscript();
}
void IList.Remove(object keyFrame) => Remove((GeometryKeyFrame)keyFrame);
public void Remove(GeometryKeyFrame keyFrame)
{
WritePreamble();
if (_keyFrames.Contains(keyFrame))
{
OnFreezablePropertyChanged(keyFrame, null);
_keyFrames.Remove(keyFrame);
WritePostscript();
}
}
public void RemoveAt(int index)
{
WritePreamble();
OnFreezablePropertyChanged(_keyFrames[index], null);
_keyFrames.RemoveAt(index);
WritePostscript();
}
object IList.this[int index]
{
get => this[index];
set => this[index] = (GeometryKeyFrame)value;
}
public GeometryKeyFrame this[int index]
{
get
{
ReadPreamble();
return _keyFrames[index];
}
set
{
if (value == null)
{
throw new ArgumentNullException(string.Format(CultureInfo.InvariantCulture, "DoubleKeyFrameCollection[{0}]", index));
}
WritePreamble();
if (value != _keyFrames[index])
{
OnFreezablePropertyChanged(_keyFrames[index], value);
_keyFrames[index] = value;
WritePostscript();
}
}
}
public bool IsReadOnly
{
get
{
ReadPreamble();
return IsFrozen;
}
}
public bool IsFixedSize
{
get
{
ReadPreamble();
return IsFrozen;
}
}
}
}
@@ -0,0 +1,43 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Expression.Drawing;
using HandyControl.Tools;
namespace HandyControl.Media.Animation
{
public class LinearGeometryKeyFrame : GeometryKeyFrame
{
public LinearGeometryKeyFrame()
{
}
public LinearGeometryKeyFrame(Geometry value) : base(value)
{
}
public LinearGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
{
}
protected override Freezable CreateInstanceCore() => new LinearGeometryKeyFrame();
protected override double[] InterpolateValueCore(double[] baseValue, double keyFrameProgress)
{
if (MathHelper.IsVerySmall(keyFrameProgress))
{
return baseValue;
}
if (MathHelper.AreClose(keyFrameProgress, 1))
{
return Numbers;
}
return AnimationHelper.InterpolateGeometryValue(baseValue, Numbers, keyFrameProgress);
}
}
}
@@ -0,0 +1,38 @@
using System;
namespace HandyControl.Media.Animation
{
internal struct ResolvedKeyFrameEntry : IComparable
{
internal int _originalKeyFrameIndex;
internal TimeSpan _resolvedKeyTime;
public int CompareTo(object other)
{
var otherEntry = (ResolvedKeyFrameEntry)other;
if (otherEntry._resolvedKeyTime > _resolvedKeyTime)
{
return -1;
}
if (otherEntry._resolvedKeyTime < _resolvedKeyTime)
{
return 1;
}
if (otherEntry._originalKeyFrameIndex > _originalKeyFrameIndex)
{
return -1;
}
if (otherEntry._originalKeyFrameIndex < _originalKeyFrameIndex)
{
return 1;
}
return 0;
}
}
}
@@ -0,0 +1,59 @@
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Expression.Drawing;
using HandyControl.Tools;
namespace HandyControl.Media.Animation
{
public class SplineGeometryKeyFrame : GeometryKeyFrame
{
public SplineGeometryKeyFrame()
{
}
public SplineGeometryKeyFrame(Geometry value) : base(value)
{
}
public SplineGeometryKeyFrame(Geometry value, KeyTime keyTime) : base(value, keyTime)
{
}
public SplineGeometryKeyFrame(Geometry value, KeyTime keyTime, KeySpline keySpline) : base(value, keyTime)
{
KeySpline = keySpline ?? throw new ArgumentNullException(nameof(keySpline));
}
protected override Freezable CreateInstanceCore() => new SplineGeometryKeyFrame();
protected override double[] InterpolateValueCore(double[] baseValue, double keyFrameProgress)
{
if (MathHelper.IsVerySmall(keyFrameProgress))
{
return baseValue;
}
if (MathHelper.AreClose(keyFrameProgress, 1))
{
return Numbers;
}
var splineProgress = KeySpline.GetSplineProgress(keyFrameProgress);
return AnimationHelper.InterpolateGeometryValue(baseValue, Numbers, splineProgress);
}
public static readonly DependencyProperty KeySplineProperty = DependencyProperty.Register(
"KeySpline", typeof(KeySpline), typeof(SplineGeometryKeyFrame), new PropertyMetadata(new KeySpline()));
public KeySpline KeySpline
{
get => (KeySpline) GetValue(KeySplineProperty);
set => SetValue(KeySplineProperty, value);
}
}
}
@@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyVersion("2.3.0")]
#endif
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Controls")]
@@ -21,6 +21,7 @@ using System.Runtime.InteropServices;
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Interactivity")]
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Expression.Shapes")]
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Expression.Media")]
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Media.Animation")]
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Data")]
[assembly: XmlnsDefinition("https://handyorg.github.io/handycontrol", "HandyControl.Properties.Langs")]
[assembly: XmlnsPrefix("https://handyorg.github.io/handycontrol", "hc")]
@@ -19,7 +19,7 @@ namespace HandyControl.Properties.Langs {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Lang {
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Confirm" xml:space="preserve">
<value>تایید</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>انصراف</value>
</data>
<data name="PngImg" xml:space="preserve">
<value>تصویر PNG</value>
</data>
<data name="ErrorImgPath" xml:space="preserve">
<value>مسیر عکس اشتباه است</value>
</data>
<data name="ErrorImgSize" xml:space="preserve">
<value>اندازه تصویر اشتباه است</value>
</data>
<data name="UnknownSize" xml:space="preserve">
<value>اندازه ناشناخته</value>
</data>
<data name="TooLarge" xml:space="preserve">
<value>خیلی بزرگ</value>
</data>
<data name="Unknown" xml:space="preserve">
<value>ناشناس</value>
</data>
<data name="Interval30s" xml:space="preserve">
<value>فاصله 30 ثانیه ای</value>
</data>
<data name="Interval1m" xml:space="preserve">
<value>فاصله 1 دقیقه ای</value>
</data>
<data name="Interval5m" xml:space="preserve">
<value>فاصله 5 دقیقه ای</value>
</data>
<data name="Interval10m" xml:space="preserve">
<value>فاصله 10 دقیقه ای</value>
</data>
<data name="Interval30m" xml:space="preserve">
<value>فاصله 30 دقیقه ای</value>
</data>
<data name="Interval1h" xml:space="preserve">
<value>فاصله 1 ساعته</value>
</data>
<data name="Interval2h" xml:space="preserve">
<value>فاصله 2 ساعته</value>
</data>
<data name="Clear" xml:space="preserve">
<value>پاک کردن</value>
</data>
<data name="Close" xml:space="preserve">
<value>بستن</value>
</data>
<data name="CloseAll" xml:space="preserve">
<value>بستن همه</value>
</data>
<data name="CloseOther" xml:space="preserve">
<value>بستن بقیه</value>
</data>
<data name="Am" xml:space="preserve">
<value>صبح</value>
</data>
<data name="Pm" xml:space="preserve">
<value>عصر</value>
</data>
<data name="Tip" xml:space="preserve">
<value>بی درنک</value>
</data>
<data name="IsNecessary" xml:space="preserve">
<value>نمی تواند خالی باشد</value>
</data>
<data name="OutOfRange" xml:space="preserve">
<value>خارج از محدوده</value>
</data>
<data name="FormatError" xml:space="preserve">
<value>خطای قالب</value>
</data>
<data name="CannotRegisterCompositeCommandInItself" xml:space="preserve">
<value>نمی توان فرمان کامپوزیت را در خود ثبت کرد</value>
</data>
<data name="CannotRegisterSameCommandTwice" xml:space="preserve">
<value>نمی توان همان فرمان را دو بار ثبت کرد</value>
</data>
<data name="Yes" xml:space="preserve">
<value>بله</value>
</data>
<data name="No" xml:space="preserve">
<value>خیر</value>
</data>
</root>
@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Confirm" xml:space="preserve">
<value>Confirmer</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="PngImg" xml:space="preserve">
<value>Image PNG</value>
</data>
<data name="ErrorImgPath" xml:space="preserve">
<value>Chemin d'image incorrect</value>
</data>
<data name="ErrorImgSize" xml:space="preserve">
<value>Taille d'image incorrect</value>
</data>
<data name="UnknownSize" xml:space="preserve">
<value>Taille inconnue</value>
</data>
<data name="TooLarge" xml:space="preserve">
<value>Trop large</value>
</data>
<data name="Unknown" xml:space="preserve">
<value>Inconnu</value>
</data>
<data name="Interval30s" xml:space="preserve">
<value>Intervale de 30 secondes</value>
</data>
<data name="Interval1m" xml:space="preserve">
<value>Intervale de de 1 minute</value>
</data>
<data name="Interval5m" xml:space="preserve">
<value>Intervale de 5 minutes</value>
</data>
<data name="Interval10m" xml:space="preserve">
<value>Intervale de 10 minutes</value>
</data>
<data name="Interval30m" xml:space="preserve">
<value>Intervale de 30 minutes</value>
</data>
<data name="Interval1h" xml:space="preserve">
<value>Intervale de 1 heure</value>
</data>
<data name="Interval2h" xml:space="preserve">
<value>Intervale de 2 heures</value>
</data>
<data name="Clear" xml:space="preserve">
<value>Effacer</value>
</data>
<data name="Close" xml:space="preserve">
<value>Fermer</value>
</data>
<data name="CloseAll" xml:space="preserve">
<value>Fermer tout</value>
</data>
<data name="CloseOther" xml:space="preserve">
<value>Fermer les autres</value>
</data>
<data name="Am" xml:space="preserve">
<value>Am</value>
</data>
<data name="Pm" xml:space="preserve">
<value>Pm</value>
</data>
<data name="Tip" xml:space="preserve">
<value>Prompt</value>
</data>
<data name="IsNecessary" xml:space="preserve">
<value>Ne peut pas être vide</value>
</data>
<data name="OutOfRange" xml:space="preserve">
<value>En dehors des limites</value>
</data>
<data name="FormatError" xml:space="preserve">
<value>Erreur de format</value>
</data>
<data name="CannotRegisterCompositeCommandInItself" xml:space="preserve">
<value>Impossible d'enregistrer une commande composite dans elle-même</value>
</data>
<data name="CannotRegisterSameCommandTwice" xml:space="preserve">
<value>Impossible d'enregistrer la même commande deux fois</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Oui</value>
</data>
<data name="No" xml:space="preserve">
<value>Non</value>
</data>
</root>
@@ -20,5 +20,8 @@
<converter:Object2VisibilityConverter x:Key="Object2VisibilityConverter"/>
<converter:Number2PercentageConverter x:Key="Number2PercentageConverter"/>
<converter:RectangleCircularConverter x:Key="RectangleCircularConverter"/>
<MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter" />
<converter:ThicknessSplitConverter x:Key="ThicknessSplitConverter"/>
<converter:CornerRadiusSplitConverter x:Key="CornerRadiusSplitConverter"/>
<MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter"/>
<converter:Double2GridLengthConverter x:Key="Double2GridLengthConverter" />
</ResourceDictionary>
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Basic/Converters.xaml"/>
@@ -47,7 +47,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<DatePickerTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource DatePickerTextBoxStyle}"/>
<Popup Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -86,7 +86,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -98,8 +98,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<DatePickerTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource DatePickerTextBoxStyle}"/>
<Popup Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -133,12 +132,12 @@
</ControlTemplate>
<ControlTemplate x:Key="DatePickerExtendLeftTemplate" TargetType="DatePicker">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -148,8 +147,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<DatePickerTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource DatePickerTextBoxStyle}"/>
<Popup Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -183,13 +181,15 @@
</ControlTemplate>
<Style x:Key="DatePickerExtendBaseStyle" BasedOn="{StaticResource DatePickerBaseStyle}" TargetType="DatePicker">
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Template" Value="{StaticResource DatePickerExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource DatePickerExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -206,7 +206,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -220,8 +220,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<DatePickerTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource DatePickerTextBoxStyle}"/>
<Popup Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -279,12 +279,12 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -296,8 +296,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource CalendarGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False"/>
<DatePickerTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource DatePickerTextBoxStyle}"/>
<Popup Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -351,7 +351,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource DatePickerPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Basic/Converters.xaml"/>
@@ -28,7 +28,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -67,7 +67,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -79,7 +79,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -113,12 +113,12 @@
</ControlTemplate>
<ControlTemplate x:Key="DateTimePickerExtendLeftTemplate" TargetType="controls:DateTimePicker">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -128,7 +128,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -162,13 +162,15 @@
</ControlTemplate>
<Style x:Key="DateTimePickerExtendBaseStyle" BasedOn="{StaticResource DateTimePickerBaseStyle}" TargetType="controls:DateTimePicker">
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Template" Value="{StaticResource DateTimePickerExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource DateTimePickerExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -185,7 +187,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -199,8 +201,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -258,12 +260,12 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -275,8 +277,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -330,7 +332,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource DateTimePickerPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -0,0 +1,63 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style x:Key="DividerBaseStyle" TargetType="controls:Divider">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Margin" Value="0,24"/>
<Setter Property="Padding" Value="24,0"/>
<Setter Property="LineStroke" Value="{DynamicResource BorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Divider">
<controls:Row>
<controls:Col Layout="12" x:Name="ColStart">
<Line VerticalAlignment="Center" StrokeDashArray="{TemplateBinding LineStrokeDashArray}" Stroke="{TemplateBinding LineStroke}" X2="1" StrokeThickness="{TemplateBinding LineStrokeThickness}" Stretch="Fill" StrokeEndLineCap="Square" StrokeStartLineCap="Square"/>
</controls:Col>
<controls:Col Layout="0">
<ContentPresenter Margin="{TemplateBinding Padding}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</controls:Col>
<controls:Col Layout="12" x:Name="ColEnd">
<Line VerticalAlignment="Center" StrokeDashArray="{TemplateBinding LineStrokeDashArray}" Stroke="{TemplateBinding LineStroke}" X2="1" StrokeThickness="{TemplateBinding LineStrokeThickness}" Stretch="Fill" StrokeEndLineCap="Square" StrokeStartLineCap="Square"/>
</controls:Col>
</controls:Row>
<ControlTemplate.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Padding" Value="0"/>
</Trigger>
<Trigger Property="HorizontalContentAlignment" Value="Left">
<Setter TargetName="ColStart" Property="Layout" Value="0"/>
<Setter TargetName="ColStart" Property="IsFixed" Value="True"/>
<Setter TargetName="ColStart" Property="Width" Value="20"/>
<Setter TargetName="ColEnd" Property="Layout" Value="24"/>
</Trigger>
<Trigger Property="HorizontalContentAlignment" Value="Right">
<Setter TargetName="ColEnd" Property="Layout" Value="0"/>
<Setter TargetName="ColEnd" Property="IsFixed" Value="True"/>
<Setter TargetName="ColEnd" Property="Width" Value="20"/>
<Setter TargetName="ColStart" Property="Layout" Value="24"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Padding" Value="0"/>
</Trigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Margin" Value="6,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Divider">
<Line HorizontalAlignment="Center" StrokeDashArray="{TemplateBinding LineStrokeDashArray}" Stroke="{TemplateBinding LineStroke}" Y2="1" StrokeThickness="{TemplateBinding LineStrokeThickness}" Stretch="Fill" StrokeEndLineCap="Square" StrokeStartLineCap="Square"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
@@ -16,7 +16,8 @@
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="controls:BorderElement.CornerRadius" Value="{StaticResource DefaultCornerRadius}"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
@@ -35,8 +36,8 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:WatermarkTextBox Focusable="True" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,16" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,16,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,14" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,14,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
@@ -62,7 +63,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Foreground="{TemplateBinding Foreground}" Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -75,8 +76,8 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:WatermarkTextBox Margin="-2,0" CaretBrush="{TemplateBinding Foreground}" Focusable="True" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,16" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,16,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,14" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,14,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
</Grid>
</Border>
</Grid>
@@ -94,12 +95,12 @@
</ControlTemplate>
<ControlTemplate x:Key="NumericUpDownExtendLeftTemplate" TargetType="controls:NumericUpDown">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Foreground="{TemplateBinding Foreground}" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -110,8 +111,8 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:WatermarkTextBox Margin="-2,0" CaretBrush="{TemplateBinding Foreground}" Focusable="True" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,16" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,16,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="5,7,5,1" Margin="0,0,0,14" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="5,1,5,7" Margin="0,14,0,0" Focusable="False" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
</Grid>
</Border>
</Grid>
@@ -130,13 +131,14 @@
<Style x:Key="NumericUpDownExtendBaseStyle" BasedOn="{StaticResource NumericUpDownBaseStyle}" TargetType="controls:NumericUpDown">
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Template" Value="{StaticResource NumericUpDownExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource NumericUpDownExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -153,7 +155,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<TextBlock FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Row="1"/>
<StackPanel Grid.Row="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
@@ -168,9 +170,9 @@
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Button Command="interactivity:ControlCommands.Clear" Name="ButtonClear" Width="16" Visibility="Collapsed" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Command="interactivity:ControlCommands.Prev" Padding="0,7,5,1" Margin="0,0,0,16" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Command="interactivity:ControlCommands.Next" Padding="0,1,5,7" Margin="0,16,0,0" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Name="ButtonClear" Width="16" Visibility="Collapsed" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Command="interactivity:ControlCommands.Prev" Padding="0,7,5,1" Margin="0,0,0,14" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Command="interactivity:ControlCommands.Next" Padding="0,1,5,7" Margin="0,14,0,0" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
</Grid>
</Border>
</Grid>
@@ -212,7 +214,7 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
@@ -230,9 +232,9 @@
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<controls:WatermarkTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Button Command="interactivity:ControlCommands.Clear" Name="PART_ButtonClear" Width="16" Visibility="Collapsed" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="0,7,5,1" Margin="0,0,0,16" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="0,1,5,7" Margin="0,16,0,0" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Name="PART_ButtonClear" Width="16" Visibility="Collapsed" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Prev" Padding="0,7,5,1" Margin="0,0,0,14" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource UpGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
<Button Visibility="{TemplateBinding ShowUpDownButton,Converter={StaticResource Boolean2VisibilityConverter}}" Command="interactivity:ControlCommands.Next" Padding="0,1,5,7" Margin="0,14,0,0" Focusable="False" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" controls:IconElement.Geometry="{StaticResource DownGeometry}" Style="{StaticResource ButtonIcon}" Width="30" VerticalAlignment="Center" Height="14"/>
</Grid>
</Border>
</Grid>
@@ -270,7 +272,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource NumericUpDownPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Basic/Converters.xaml"/>
@@ -54,7 +54,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -83,12 +83,12 @@
</ControlTemplate>
<ControlTemplate x:Key="PasswordBoxExtendLeftTemplate" TargetType="PasswordBox">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -115,15 +115,16 @@
</ControlTemplate>
<Style x:Key="PasswordBoxExtendBaseStyle" BasedOn="{StaticResource PasswordBoxBaseStyle}" TargetType="PasswordBox">
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="controls:PasswordBoxAttach.IsMonitoring" Value="True"/>
<Setter Property="Template" Value="{StaticResource PasswordBoxExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource PasswordBoxExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -169,7 +170,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
@@ -228,14 +229,14 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="0,8,6,8">
<StackPanel Grid.Column="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -291,17 +292,17 @@
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Padding" Value="{StaticResource DefaultInputPadding}"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.PositiveInfinity}"/>
<Setter Property="controls:PasswordBoxAttach.IsMonitoring" Value="True"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template" Value="{StaticResource PasswordBoxPlusTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource PasswordBoxPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -142,8 +142,11 @@
<TextBlock Margin="0,10,0,0" Visibility="{Binding ShowText,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{TemplateBinding Foreground}" Text="{TemplateBinding Text}"/>
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource StoryboardOnLoaded}"/>
<EventTrigger RoutedEvent="FrameworkElement.Loaded" SourceName="PART_Wave">
<BeginStoryboard Name="BeginStoryboardWave" Storyboard="{StaticResource StoryboardOnLoaded}"/>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.Unloaded" SourceName="PART_Wave">
<StopStoryboard BeginStoryboardName="BeginStoryboardWave"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
@@ -1,7 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib">
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ToggleButtonBaseStyle.xaml"/>
@@ -32,7 +31,7 @@
<ControlTemplate TargetType="controls:ProgressButton">
<Border x:Name="Chrome" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
<controls:SimplePanel>
<ProgressBar x:Name="ProgressBar" Height="{x:Static system:Double.NaN}" Value="{TemplateBinding Progress}" Maximum="100" Visibility="Collapsed" Style="{TemplateBinding ProgressStyle}"/>
<ProgressBar x:Name="ProgressBar" Height="Auto" Value="{TemplateBinding Progress}" Maximum="100" Visibility="Collapsed" Style="{TemplateBinding ProgressStyle}"/>
<ContentPresenter Name="UnCheckedElement" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<ContentPresenter Name="CheckedElement" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Visibility="Collapsed" Content="{Binding Path=(controls:StatusSwitchElement.CheckedElement),RelativeSource={RelativeSource TemplatedParent}}"/>
</controls:SimplePanel>
@@ -0,0 +1,39 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="BaseStyle.xaml"/>
<ResourceDictionary Source="../../Basic/Sizes.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="RunningBlockBaseStyle" BasedOn="{StaticResource BaseStyle}" TargetType="controls:RunningBlock">
<Setter Property="controls:BorderElement.CornerRadius" Value="{StaticResource DefaultCornerRadius}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="0,10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:RunningBlock">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" Padding="{TemplateBinding Padding}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" ClipToBounds="True">
<controls:SimplePanel HorizontalAlignment="Left" x:Name="PART_Panel">
<ContentPresenter x:Name="PART_ContentElement" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
<ContentPresenter.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</controls:SimplePanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Padding" Value="10,0"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
@@ -22,7 +22,45 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle x:Name="rectangle" RadiusX="4" RadiusY="4" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}" Fill="{TemplateBinding Background}"/>
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="8"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusX)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="4"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusY)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="4"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="2"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusX)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusY)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="-2"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border Width="{TemplateBinding Width}" Background="Transparent">
<Rectangle x:Name="rectangle" RadiusX="1" RadiusY="1" HorizontalAlignment="Right" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="2" Fill="{TemplateBinding Background}">
<Rectangle.RenderTransform>
<TransformGroup>
<TranslateTransform X="-2"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource SecondaryTextBrush}"/>
@@ -30,6 +68,12 @@
<Trigger Property="IsDragging" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource PrimaryTextBrush}"/>
</Trigger>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource Storyboard2}"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
@@ -42,7 +86,45 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle x:Name="rectangle" RadiusX="4" RadiusY="4" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}" Fill="{TemplateBinding Background}"/>
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Height" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="8"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusX)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="4"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusY)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="4"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Height" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="2"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusX)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Rectangle.RadiusY)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value="-2"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border Height="{TemplateBinding Height}" Background="Transparent">
<Rectangle x:Name="rectangle" RadiusX="4" RadiusY="4" VerticalAlignment="Bottom" Height="2" SnapsToDevicePixels="True" Width="{TemplateBinding Width}" Fill="{TemplateBinding Background}">
<Rectangle.RenderTransform>
<TransformGroup>
<TranslateTransform Y="-2"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource SecondaryTextBrush}"/>
@@ -50,6 +132,12 @@
<Trigger Property="IsDragging" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource PrimaryTextBrush}"/>
</Trigger>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource Storyboard2}"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
@@ -120,10 +208,10 @@
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_VerticalScrollBar">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value=".8"/>
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value=".8"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_HorizontalScrollBar">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value=".8"/>
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value=".8"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2">
@@ -168,10 +256,10 @@
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_VerticalScrollBar">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value=".8"/>
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value=".8"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_HorizontalScrollBar">
<EasingDoubleKeyFrame KeyTime="0:0:.2" Value=".8"/>
<EasingDoubleKeyFrame KeyTime="0:0:.1" Value=".8"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2">
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TextBoxBaseStyle.xaml"/>
@@ -18,7 +18,7 @@
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<ScrollViewer Margin="-2,0" Grid.Row="0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
</Border>
@@ -42,7 +42,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -54,7 +54,7 @@
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="0" Grid.Column="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource TextBlockDefaultThiLight}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}"/>
<ScrollViewer Margin="-2,0" Grid.Row="0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
@@ -74,12 +74,12 @@
</ControlTemplate>
<ControlTemplate x:Key="SearchBarExtendLeftTemplate" TargetType="controls:SearchBar">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -89,7 +89,7 @@
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="0" Grid.Column="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource TextBlockDefaultThiLight}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}"/>
<ScrollViewer Margin="-2,0" Grid.Row="0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
@@ -109,13 +109,15 @@
</ControlTemplate>
<Style x:Key="SearchBarExtendBaseStyle" BasedOn="{StaticResource SearchBarBaseStyle}" TargetType="controls:SearchBar">
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Template" Value="{StaticResource SearchBarExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource SearchBarExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -132,7 +134,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -146,8 +148,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="0" Grid.Column="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource TextBlockDefaultThiLight}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}"/>
<ScrollViewer Margin="-2,0" Grid.Row="0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
@@ -191,12 +193,12 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -208,8 +210,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Search" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource SearchGeometry}" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="0" Grid.Column="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{StaticResource TextBlockDefaultThiLight}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}"/>
<ScrollViewer Margin="-2,0" Grid.Row="0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
@@ -249,7 +251,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource SearchBarPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -0,0 +1,85 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MenuBaseStyle.xaml"/>
<ResourceDictionary Source="../ToggleButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SplitButtonBaseStyle" BasedOn="{StaticResource BaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Height" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="Padding" Value="{StaticResource DefaultControlPadding}"/>
<Setter Property="Foreground" Value="{DynamicResource TextIconBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
<Setter Property="controls:BorderElement.CornerRadius" Value="{StaticResource DefaultCornerRadius}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:SplitButton">
<controls:SimplePanel x:Name="templateRoot">
<Border Background="{TemplateBinding Background}" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}"/>
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}">
<Path x:Name="PathMain" Width="{TemplateBinding controls:IconElement.Width}" Height="{TemplateBinding controls:IconElement.Height}" Fill="{TemplateBinding Foreground}" SnapsToDevicePixels="True" Stretch="Uniform" Data="{TemplateBinding controls:IconElement.Geometry}"/>
<ContentPresenter x:Name="ContentPresenterMain" RecognizesAccessKey="True" VerticalAlignment="Center" Margin="6,0,0,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</StackPanel>
<ToggleButton x:Name="PART_Arrow" Foreground="{TemplateBinding Foreground}" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Width="22" Height="Auto" Padding="0,10,8,10" HorizontalContentAlignment="Left" Grid.Column="1" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.GeometrySelected="{StaticResource UpGeometry}" controls:IconElement.Geometry="{StaticResource DownGeometry}"/>
</Grid>
</Border>
<Popup AllowsTransparency="true" StaysOpen="False" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="Fade" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ContentPresenter ContentSource="DropDownContent"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
</controls:SimplePanel>
<ControlTemplate.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" TargetName="ContentPresenterMain"/>
</Trigger>
<Trigger Property="controls:IconElement.Geometry" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" TargetName="PathMain"/>
<Setter Property="Margin" Value="0" TargetName="ContentPresenterMain"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HitMode" Value="Click"/>
<Condition Property="IsChecked" Value="True" SourceName="PART_Arrow"/>
</MultiTrigger.Conditions>
<Setter Property="IsDropDownOpen" Value="True"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".9"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value=".6"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.4"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Basic/Converters.xaml"/>
@@ -73,7 +73,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}" Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -99,12 +99,12 @@
</ControlTemplate>
<ControlTemplate x:Key="TextBoxExtendLeftTemplate" TargetType="TextBox">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -129,13 +129,14 @@
<Style x:Key="TextBoxExtendBaseStyle" BasedOn="{StaticResource TextBoxBaseStyle}" TargetType="TextBox">
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Template" Value="{StaticResource TextBoxExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource TextBoxExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -152,7 +153,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<TextBlock FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Row="1"/>
<StackPanel Grid.Row="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
@@ -167,7 +168,7 @@
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}" HorizontalAlignment="Stretch" Style="{StaticResource TextBlockDefaultThiLight}" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}"/>
<ScrollViewer Style="{x:Null}" Margin="-2,0" Grid.Column="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<Button Command="interactivity:ControlCommands.Clear" Margin="0,0,7,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Margin="0,0,7,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
</Grid>
</Border>
</Grid>
@@ -209,13 +210,13 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Column="1"/>
<StackPanel Grid.Column="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Grid.Column="0" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -227,7 +228,7 @@
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="{TemplateBinding Text,Converter={StaticResource String2VisibilityReConverter}}" HorizontalAlignment="Stretch" Style="{StaticResource TextBlockDefaultThiLight}" Text="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}"/>
<ScrollViewer Style="{x:Null}" Grid.Column="0" Margin="-2,0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<Button Command="interactivity:ControlCommands.Clear" Margin="0,0,7,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Margin="0,0,7,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
</Grid>
</Border>
</Grid>
@@ -265,7 +266,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource TextBoxPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
xmlns:interactivity="clr-namespace:HandyControl.Interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Basic/Geometries.xaml"/>
@@ -28,7 +28,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -67,7 +67,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -79,7 +79,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -113,12 +113,12 @@
</ControlTemplate>
<ControlTemplate x:Key="TimePickerExtendLeftTemplate" TargetType="controls:TimePicker">
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -128,7 +128,7 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ButtonIcon}" Padding="7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="1" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -162,13 +162,15 @@
</ControlTemplate>
<Style x:Key="TimePickerExtendBaseStyle" BasedOn="{StaticResource TimePickerBaseStyle}" TargetType="controls:TimePicker">
<Setter Property="Height" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="controls:InfoElement.Symbol" Value="●"/>
<Setter Property="controls:InfoElement.ContentHeight" Value="{x:Static system:Double.NaN}"/>
<Setter Property="controls:InfoElement.MinContentHeight" Value="{StaticResource DefaultControlHeight}"/>
<Setter Property="Template" Value="{StaticResource TimePickerExtendTopTemplate}"/>
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource TimePickerExtendLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -185,7 +187,7 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
<RowDefinition MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Double2GridLengthConverter}}"/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
@@ -199,8 +201,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox x:Name="PART_TextBox" Padding="{TemplateBinding Padding}" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -258,12 +260,12 @@
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid MinHeight="{Binding Path=(controls:InfoElement.MinContentHeight),RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8">
<StackPanel Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,7,6,7">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
@@ -275,8 +277,8 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Button Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Style="{StaticResource ButtonIcon}" Padding="2,7,7,7" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<Button Height="{x:Static system:Double.NaN}" Command="interactivity:ControlCommands.Clear" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="1" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{Binding BorderBrush,ElementName=templateRoot}"/>
<Button Height="{x:Static system:Double.NaN}" Style="{StaticResource ButtonIcon}" Padding="2,6,7,6" controls:IconElement.Geometry="{StaticResource ClockGeometry}" x:Name="PART_Button" Grid.Column="2" Foreground="{Binding BorderBrush,ElementName=templateRoot}" Focusable="False" Grid.Row="0"/>
<controls:WatermarkTextBox Padding="{TemplateBinding Padding}" x:Name="PART_TextBox" Watermark="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Grid.Row="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Popup TextElement.FontSize="12" Grid.Column="0" VerticalOffset="1" x:Name="PART_Popup" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
@@ -330,7 +332,7 @@
<Style.Triggers>
<Trigger Property="controls:InfoElement.TitleAlignment" Value="Left">
<Setter Property="Template" Value="{StaticResource TimePickerPlusLeftTemplate}"/>
<Setter Property="Width" Value="{x:Static system:Double.NaN}"/>
<Setter Property="Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -4,10 +4,12 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Basic/Converters.xaml"/>
<ResourceDictionary Source="../Basic/Sizes.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--用于包裹一个区域-->
<Style x:Key="BorderRegion" TargetType="Border">
<Setter Property="CornerRadius" Value="{StaticResource DefaultCornerRadius}"/>
<Setter Property="Padding" Value="10"/>
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
@@ -0,0 +1,10 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Base/DividerBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource DividerBaseStyle}" TargetType="controls:Divider"/>
</ResourceDictionary>
@@ -0,0 +1,16 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style TargetType="controls:FloatingBlock">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:FloatingBlock">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,82 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Basic/Converters.xaml"/>
<ResourceDictionary Source="../Basic/Geometries.xaml"/>
<ResourceDictionary Source="../Basic/Effects.xaml"/>
<ResourceDictionary Source="TextBlock.xaml"/>
<ResourceDictionary Source="Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="controls:GrowlWindow">
<Setter Property="controls:WindowAttach.IgnoreAltF4" Value="True"/>
<Setter Property="controls:WindowAttach.ShowInTaskManager" Value="False"/>
<Setter Property="Width" Value="340"/>
<Setter Property="MaxWidth" Value="340"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ShowActivated" Value="False"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="Topmost" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:GrowlWindow">
<controls:ScrollViewer VerticalScrollBarVisibility="Hidden" IsEnableInertia="True">
<StackPanel Name="PART_GrowPanel" VerticalAlignment="Top" Margin="0,10,10,10"/>
</controls:ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="controls:Growl">
<Setter Property="Focusable" Value="False"/>
<Setter Property="MinHeight" Value="60"/>
<Setter Property="Width" Value="320"/>
<Setter Property="Margin" Value="10,0,0,10"/>
<Setter Property="MaxWidth" Value="320"/>
<Setter Property="controls:BorderElement.CornerRadius" Value="8"/>
<Setter Property="Background" Value="{DynamicResource ThirdlyRegionBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Growl">
<Grid Name="PART_GridMain" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform X="{TemplateBinding MaxWidth}"/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.ColumnSpan="3" Grid.RowSpan="2" Effect="{StaticResource EffectShadow2}" Background="{TemplateBinding Background}" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" Width="320"/>
<Path Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="0,15,0,0" Width="30" Height="30" Data="{TemplateBinding Icon}" Stretch="Uniform" Fill="{TemplateBinding IconBrush}"/>
<StackPanel VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" Margin="0,10,10,10">
<TextBlock Text="{TemplateBinding Message}" Style="{StaticResource TextBlockDefault}" HorizontalAlignment="Left" TextWrapping="Wrap"/>
<TextBlock Visibility="{Binding ShowDateTime,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}" Text="{Binding Time,RelativeSource={RelativeSource AncestorType=controls:Growl},StringFormat=yyyy/MM/dd HH:mm:ss}" Style="{StaticResource TextBlockDefault}" Foreground="{DynamicResource SecondaryTextBrush}" HorizontalAlignment="Left" Margin="0,4,0,0"/>
</StackPanel>
<Button Grid.Row="0" Visibility="Collapsed" Margin="11,0" Name="PART_ButtonClose" Command="interactivity:ControlCommands.Close" Grid.Column="2" Background="Transparent" Style="{StaticResource ButtonCustom}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="18" Height="18">
<Path Data="{StaticResource ErrorGeometry}" Stretch="Uniform" Fill="{DynamicResource SecondaryTextBrush}"/>
</Button>
<StackPanel Name="PART_PanelMore" IsEnabled="False" Visibility="Collapsed" Orientation="Horizontal" Grid.Row="1" Grid.ColumnSpan="3" Height="28" Grid.Column="0">
<Button Command="interactivity:ControlCommands.Cancel" Style="{StaticResource ButtonCustom}" Width="160">
<TextBlock Text="{Binding CancelStr,RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" Foreground="{DynamicResource DangerBrush}"/>
</Button>
<Button Command="interactivity:ControlCommands.Confirm" Style="{StaticResource ButtonCustom}" Width="160">
<TextBlock Text="{Binding ConfirmStr,RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" Foreground="{DynamicResource PrimaryBrush}"/>
</Button>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,22 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style TargetType="controls:Notification">
<Setter Property="controls:WindowAttach.IgnoreAltF4" Value="True"/>
<Setter Property="controls:WindowAttach.ShowInTaskManager" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ShowActivated" Value="False"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="Topmost" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Notification">
<ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,10 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Base/RunningBlockBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource RunningBlockBaseStyle}" TargetType="controls:RunningBlock"/>
</ResourceDictionary>
@@ -0,0 +1,42 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Base/SplitButtonBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource DarkDefaultBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource BorderBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="SplitButtonPrimary" BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Background" Value="{DynamicResource PrimaryBrush}"/>
</Style>
<Style x:Key="SplitButtonSuccess" BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Background" Value="{DynamicResource SuccessBrush}"/>
</Style>
<Style x:Key="SplitButtonInfo" BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Background" Value="{DynamicResource InfoBrush}"/>
</Style>
<Style x:Key="SplitButtonWarning" BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Background" Value="{DynamicResource WarningBrush}"/>
</Style>
<Style x:Key="SplitButtonDanger" BasedOn="{StaticResource SplitButtonBaseStyle}" TargetType="controls:SplitButton">
<Setter Property="Background" Value="{DynamicResource DangerBrush}"/>
</Style>
</ResourceDictionary>
@@ -0,0 +1,22 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style TargetType="controls:Sprite">
<Setter Property="controls:WindowAttach.IgnoreAltF4" Value="True"/>
<Setter Property="controls:WindowAttach.ShowInTaskManager" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ShowActivated" Value="False"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="Topmost" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Sprite">
<ContentPresenter Margin="{TemplateBinding Padding}" controls:WindowAttach.IsDragElement="True" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -70,6 +70,12 @@
<ResourceDictionary Source="Rectangle.xaml"/>
<ResourceDictionary Source="Magnifier.xaml"/>
<ResourceDictionary Source="ToggleBlock.xaml"/>
<ResourceDictionary Source="RunningBlock.xaml"/>
<ResourceDictionary Source="Sprite.xaml"/>
<ResourceDictionary Source="Notification.xaml"/>
<ResourceDictionary Source="FloatingBlock.xaml"/>
<ResourceDictionary Source="SplitButton.xaml"/>
<ResourceDictionary Source="Divider.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -13,6 +13,12 @@
<ResourceDictionary Source="Base/TabControlBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ContextMenu x:Key="TabItemMenu" x:Shared="False">
<MenuItem Command="interactivity:ControlCommands.Close" Header="{x:Static langs:Lang.Close}"/>
<MenuItem Command="interactivity:ControlCommands.CloseAll" Header="{x:Static langs:Lang.CloseAll}"/>
<MenuItem Command="interactivity:ControlCommands.CloseOther" Header="{x:Static langs:Lang.CloseOther}"/>
</ContextMenu>
<Style TargetType="controls:TabItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
@@ -23,6 +29,7 @@
<Setter Property="Padding" Value="16,0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Menu" Value="{StaticResource TabItemMenu}"/>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
@@ -33,18 +40,11 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:TabItem">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true" ContextMenu="{TemplateBinding Menu}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Command="interactivity:ControlCommands.Close" Header="{x:Static langs:Lang.Close}"/>
<MenuItem Command="interactivity:ControlCommands.CloseAll" Header="{x:Static langs:Lang.CloseAll}"/>
<MenuItem Command="interactivity:ControlCommands.CloseOther" Header="{x:Static langs:Lang.CloseOther}"/>
</ContextMenu>
</Grid.ContextMenu>
<Border Grid.ColumnSpan="2" BorderThickness="{TemplateBinding BorderThickness}" x:Name="mainBorder" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Margin="0">
<Border Margin="0,0,0,-1" x:Name="innerBorder" Background="{DynamicResource RegionBrush}" Opacity="0"/>
</Border>
@@ -56,7 +56,7 @@
</LinearGradientBrush>
</ContentPresenter.OpacityMask>
</ContentPresenter>
<Button Grid.Column="1" Focusable="False" Command="interactivity:ControlCommands.Close" Visibility="{Binding ShowCloseButton,RelativeSource={RelativeSource AncestorType=controls:TabControl},Converter={StaticResource Boolean2VisibilityConverter}}" Background="Transparent" Style="{StaticResource ButtonCustom}" Width="28">
<Button Grid.Column="1" Focusable="False" Command="interactivity:ControlCommands.Close" Visibility="{TemplateBinding ShowCloseButton,Converter={StaticResource Boolean2VisibilityConverter}}" Background="Transparent" Style="{StaticResource ButtonCustom}" Width="28">
<Path Fill="{DynamicResource PrimaryTextBrush}" Width="8" Height="8" Style="{StaticResource ClosePathStyle}"/>
</Button>
</Grid>
@@ -11,7 +11,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Background="White" Padding="{TemplateBinding Padding}" BorderThickness="1" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{DynamicResource BorderBrush}">
<Border Background="{DynamicResource RegionBrush}" Padding="{TemplateBinding Padding}" BorderThickness="1" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{DynamicResource BorderBrush}">
<ContentPresenter Margin="10,0"/>
</Border>
</ControlTemplate>
@@ -19,4 +19,4 @@
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary>
@@ -11,7 +11,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:TransitioningContentControl">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<controls:SimplePanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PresentationStates">
<VisualState x:Name="DefaultTransition">
@@ -76,29 +76,27 @@
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<controls:SimplePanel>
<ContentPresenter x:Name="PreviousContentPresentationSite" Content="{x:Null}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ContentPresenter x:Name="CurrentContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</controls:SimplePanel>
</Border>
<ContentPresenter x:Name="PreviousContentPresentationSite" Content="{x:Null}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ContentPresenter x:Name="CurrentContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</controls:SimplePanel>
</ControlTemplate>
</Setter.Value>
</Setter>
@@ -0,0 +1,161 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Security;
using System.Text;
using HandyControl.Tools.Extension;
namespace HandyControl.Tools.Converter
{
public class ColLayoutConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType)
{
switch (Type.GetTypeCode(sourceType))
{
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
case TypeCode.String:
return true;
default:
return false;
}
}
public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) =>
destinationType == typeof(InstanceDescriptor) || destinationType == typeof(string);
public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object source)
{
if (source == null) throw GetConvertFromException(null);
switch (source)
{
case string s:
return FromString(s, cultureInfo);
case double d:
return new ColLayout((int)d);
default:
return new ColLayout(Convert.ToInt32(source, cultureInfo));
}
}
[SecurityCritical]
public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType)
{
if (value == null) throw new ArgumentNullException(nameof(value));
if (destinationType == null) throw new ArgumentNullException(nameof(destinationType));
if (!(value is ColLayout)) throw new ArgumentException("UnexpectedParameterType");
var th = (ColLayout)value;
if (destinationType == typeof(string)) return ToString(th, cultureInfo);
if (destinationType == typeof(InstanceDescriptor))
{
var ci = typeof(ColLayout).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
return new InstanceDescriptor(ci, new object[] { th.Xs, th.Sm, th.Md, th.Lg, th.Xl, th.Xxl });
}
throw new ArgumentException("CannotConvertType");
}
private static string ToString(ColLayout th, CultureInfo cultureInfo)
{
var listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo);
// Initial capacity [128] is an estimate based on a sum of:
// 72 = 6x double (twelve digits is generous for the range of values likely)
// 4 = 4x separator characters
var sb = new StringBuilder(128);
sb.Append(th.Xs.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(th.Sm.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(th.Md.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(th.Lg.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(th.Xl.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(th.Xxl.ToString(cultureInfo));
return th.ToString();
}
private static ColLayout FromString(string s, CultureInfo cultureInfo)
{
var th = new TokenizerHelper(s, cultureInfo);
var lengths = new int[6];
var i = 0;
while (th.NextToken())
{
if (i >= 6)
{
i = 7; // Set i to a bad value.
break;
}
lengths[i] = th.GetCurrentToken().Value<int>();
i++;
}
switch (i)
{
case 1:
return new ColLayout(lengths[0]);
case 2:
return new ColLayout
{
Xs = lengths[0],
Sm = lengths[1]
};
case 3:
return new ColLayout
{
Xs = lengths[0],
Sm = lengths[1],
Md = lengths[2]
};
case 4:
return new ColLayout
{
Xs = lengths[0],
Sm = lengths[1],
Md = lengths[2],
Lg = lengths[3]
};
case 5:
return new ColLayout
{
Xs = lengths[0],
Sm = lengths[1],
Md = lengths[2],
Lg = lengths[3],
Xl = lengths[4]
};
case 6:
return new ColLayout
{
Xs = lengths[0],
Sm = lengths[1],
Md = lengths[2],
Lg = lengths[3],
Xl = lengths[4],
Xxl = lengths[5]
};
}
throw new FormatException("InvalidStringColLayout");
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace HandyControl.Tools.Converter
{
public class CornerRadiusSplitConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is CornerRadius cornerRadius)
{
if (parameter is string str)
{
var arr = str.Split(',');
if (arr.Length != 4) return cornerRadius;
return new CornerRadius(arr[0].Equals("1") ? cornerRadius.TopLeft : 0,
arr[1].Equals("1") ? cornerRadius.TopRight : 0,
arr[1].Equals("1") ? cornerRadius.BottomRight : 0,
arr[1].Equals("1") ? cornerRadius.BottomLeft : 0);
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,29 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace HandyControl.Tools.Converter
{
public class Double2GridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double doubleValue)
{
if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
{
return new GridLength(1.0, GridUnitType.Star);
}
return new GridLength(doubleValue);
}
return new GridLength(0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace HandyControl.Tools.Converter
{
public class ThicknessSplitConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Thickness thickness)
{
if (parameter is string str)
{
var arr = str.Split(',');
if (arr.Length != 4) return thickness;
return new Thickness(arr[0].Equals("1") ? thickness.Left : 0,
arr[1].Equals("1") ? thickness.Top : 0,
arr[1].Equals("1") ? thickness.Right : 0,
arr[1].Equals("1") ? thickness.Bottom : 0);
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
@@ -1,13 +1,20 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Windows.Markup;
using HandyControl.Data;
using HandyControl.Tools.Converter;
namespace HandyControl.Tools.Extension
{
[TypeConverter(typeof(ColLayoutConverter))]
public class ColLayout : MarkupExtension
{
public static readonly int ColMaxCellCount = 24;
public static readonly int HalfColMaxCellCount = 12;
public static readonly int XsMaxWidth = 768;
public static readonly int SmMaxWidth = 992;
@@ -30,6 +37,31 @@ namespace HandyControl.Tools.Extension
public int Xxl { get; set; } = 2;
public ColLayout()
{
}
public ColLayout(int uniformWidth)
{
Xs = uniformWidth;
Sm = uniformWidth;
Md = uniformWidth;
Lg = uniformWidth;
Xl = uniformWidth;
Xxl = uniformWidth;
}
public ColLayout(int xs, int sm, int md, int lg, int xl, int xxl)
{
Xs = xs;
Sm = sm;
Md = md;
Lg = lg;
Xl = xl;
Xxl = xxl;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new ColLayout
@@ -67,5 +99,29 @@ namespace HandyControl.Tools.Extension
}
return ColLayoutStatus.Xxl;
}
public override string ToString()
{
var cultureInfo = CultureInfo.CurrentCulture;
var listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo);
// Initial capacity [128] is an estimate based on a sum of:
// 72 = 6x double (twelve digits is generous for the range of values likely)
// 4 = 4x separator characters
var sb = new StringBuilder(128);
sb.Append(Xs.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(Sm.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(Md.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(Lg.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(Xl.ToString(cultureInfo));
sb.Append(listSeparator);
sb.Append(Xxl.ToString(cultureInfo));
return sb.ToString();
}
}
}
@@ -0,0 +1,117 @@
using System;
using System.Windows;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Tools
{
public class HatchBrushGenerator
{
private static readonly byte[][] HatchBrushes =
{
new byte[] {0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00}, // Horizontal
new byte[] {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, // Vertical
new byte[] {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, // ForwardDiagonal
new byte[] {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, // BackwardDiagonal
new byte[] {0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08}, // Cross
new byte[] {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81}, // DiagonalCross
new byte[] {0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80}, // Percent05
new byte[] {0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88}, // Percent10
new byte[] {0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc}, // Percent20
new byte[] {0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc}, // Percent25
new byte[] {0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc}, // Percent30
new byte[] {0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc}, // Percent40
new byte[] {0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc}, // Percent50
new byte[] {0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee}, // Percent60
new byte[] {0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff}, // Percent70
new byte[] {0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff}, // Percent75
new byte[] {0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff}, // Percent80
new byte[] {0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff}, // Percent90
new byte[] {0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}, // LightDownwardDiagonal
new byte[] {0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11}, // LightUpwardDiagonal
new byte[] {0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc}, // DarkDownwardDiagonal
new byte[] {0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99}, // DarkUpwardDiagonal
new byte[] {0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0}, // WideDownwardDiagonal
new byte[] {0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1}, // WideUpwardDiagonal
new byte[] {0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}, // LightVertical
new byte[] {0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff}, // LightHorizontal
new byte[] {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, // NarrowVertical
new byte[] {0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff}, // NarrowHorizontal
new byte[] {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc}, // DarkVertical
new byte[] {0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff}, // DarkHorizontal
new byte[] {0x11, 0x22, 0x44, 0x88, 0x00, 0x00, 0x00, 0x00}, // DashedDownwardDiagonal
new byte[] {0x88, 0x44, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}, // DashedUpwardDiagonal
new byte[] {0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00}, // DashedHorizontal
new byte[] {0x01, 0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10}, // DashedVertical
new byte[] {0x01, 0x08, 0x80, 0x10, 0x02, 0x40, 0x04, 0x20}, // SmallConfetti
new byte[] {0x03, 0x63, 0x6c, 0x0c, 0xc0, 0xc6, 0x36, 0x30}, // LargeConfetti
new byte[] {0x03, 0x84, 0x48, 0x30, 0x03, 0x84, 0x48, 0x30}, // ZigZag
new byte[] {0x30, 0x49, 0x06, 0x00, 0x30, 0x49, 0x06, 0x00}, // Wave
new byte[] {0x81, 0x42, 0x24, 0x18, 0x08, 0x04, 0x02, 0x01}, // DiagonalBrick
new byte[] {0xff, 0x01, 0x01, 0x01, 0xff, 0x10, 0x10, 0x10}, // HorizontalBrick
new byte[] {0x11, 0x82, 0x44, 0xa8, 0x11, 0xa2, 0x44, 0x2a}, // Weave
new byte[] {0x55, 0xaa, 0x55, 0xaa, 0x0f, 0x0f, 0x0f, 0x0f}, // Plaid
new byte[] {0x02, 0x01, 0x02, 0x00, 0x10, 0x20, 0x10, 0x00}, // Divot
new byte[] {0x55, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}, // DottedGrid
new byte[] {0x11, 0x00, 0x04, 0x00, 0x11, 0x00, 0x40, 0x00}, // DottedDiamond
new byte[] {0x03, 0x0c, 0x10, 0x20, 0x20, 0x30, 0x48, 0x84}, // Shingle
new byte[] {0xff, 0x33, 0xff, 0xcc, 0xff, 0x33, 0xff, 0xcc}, // Trellis
new byte[] {0xee, 0x19, 0x1f, 0x1f, 0xee, 0x91, 0xf1, 0xf1}, // Sphere
new byte[] {0xff, 0x11, 0x11, 0x11, 0xff, 0x11, 0x11, 0x11}, // SmallGrid
new byte[] {0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc}, // SmallCheckerBoard
new byte[] {0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0}, // LargeCheckerBoard
new byte[] {0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82}, // OutlinedDiamond
new byte[] {0x08, 0x1c, 0x3e, 0x7f, 0x3e, 0x1c, 0x08, 0x00} // SolidDiamond
};
public Brush GetHatchBrush(HatchStyle hatchStyle, Color foreColor, Color backColor)
{
var hatchData = GetHatchData(hatchStyle);
var foreGeometryGroup = new GeometryGroup();
for (var y = 0; y < 8; y++)
{
for (var x = 0; x < 8; x++)
{
if ((hatchData[y] & (0x80 >> x)) > 0)
{
foreGeometryGroup.Children.Add(new RectangleGeometry(new Rect(x, y, 1, 1)));
}
}
}
var drawingBrush = new DrawingBrush
{
Viewport = new Rect(0, 0, 8, 8),
ViewportUnits = BrushMappingMode.Absolute,
Stretch = Stretch.None,
TileMode = TileMode.Tile,
Drawing = new DrawingGroup
{
Children =
{
new GeometryDrawing
{
Brush = new SolidColorBrush(backColor),
Geometry = new RectangleGeometry(new Rect(0, 0, 8, 8))
},
new GeometryDrawing
{
Brush = new SolidColorBrush(foreColor),
Geometry = foreGeometryGroup
}
}
}
};
RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache);
return drawingBrush;
}
private byte[] GetHatchData(HatchStyle hatchStyle) =>
hatchStyle < HatchStyle.Horizontal || hatchStyle > HatchStyle.SolidDiamond
? throw new ArgumentOutOfRangeException(nameof(hatchStyle))
: HatchBrushes[(int)hatchStyle];
}
}
@@ -1,6 +1,10 @@
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Tools.Extension;
namespace HandyControl.Tools
{
@@ -15,7 +19,7 @@ namespace HandyControl.Tools
/// <param name="thickness"></param>
/// <param name="milliseconds"></param>
/// <returns></returns>
public static ThicknessAnimation CreateAnimation(Thickness thickness = default(Thickness), double milliseconds = 200)
public static ThicknessAnimation CreateAnimation(Thickness thickness = default, double milliseconds = 200)
{
return new ThicknessAnimation(thickness, new Duration(TimeSpan.FromMilliseconds(milliseconds)))
{
@@ -36,5 +40,55 @@ namespace HandyControl.Tools
EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut }
};
}
internal static void DecomposeGeometryStr(string geometryStr, out double[] arr)
{
var collection = Regex.Matches(geometryStr, RegularPatterns.DigitsPattern);
arr = new double[collection.Count];
for (var i = 0; i < collection.Count; i++)
{
arr[i] = collection[i].Value.Value<double>();
}
}
internal static Geometry ComposeGeometry(string[] strings, double[] arr)
{
var builder = new StringBuilder(strings[0]);
for (var i = 0; i < arr.Length; i++)
{
var s = strings[i + 1];
var n = arr[i];
if (!double.IsNaN(n))
{
builder.Append(n).Append(s);
}
}
return Geometry.Parse(builder.ToString());
}
internal static Geometry InterpolateGeometry(double[] from, double[] to, double progress, string[] strings)
{
var accumulated = new double[to.Length];
for (var i = 0; i < to.Length; i++)
{
var fromValue = from[i];
accumulated[i] = fromValue + (to[i] - fromValue) * progress;
}
return ComposeGeometry(strings, accumulated);
}
internal static double[] InterpolateGeometryValue(double[] from, double[] to, double progress)
{
var accumulated = new double[to.Length];
for (var i = 0; i < to.Length; i++)
{
var fromValue = from[i];
accumulated[i] = fromValue + (to[i] - fromValue) * progress;
}
return accumulated;
}
}
}
@@ -66,4 +66,4 @@ namespace HandyControl.Tools
}
#endif
}
}
}
@@ -1,54 +0,0 @@
using System;
using System.Text;
namespace HandyControl.Tools
{
internal class CreateParams
{
public string ClassName { get; set; }
public string Caption { get; set; }
public int Style { get; set; }
public int ExStyle{ get; set; }
public int ClassStyle { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public IntPtr Parent { get; set; }
public object Param { get; set; }
public override string ToString()
{
var sb = new StringBuilder(64);
sb.Append("CreateParams {'");
sb.Append(ClassName);
sb.Append("', '");
sb.Append(Caption);
sb.Append("', 0x");
sb.Append(Convert.ToString(Style, 16));
sb.Append(", 0x");
sb.Append(Convert.ToString(ExStyle, 16));
sb.Append(", {");
sb.Append(X);
sb.Append(", ");
sb.Append(Y);
sb.Append(", ");
sb.Append(Width);
sb.Append(", ");
sb.Append(Height);
sb.Append("}");
sb.Append("}");
return sb.ToString();
}
}
}
@@ -0,0 +1,233 @@
//---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: TokenizerHelper.cs
//
// Description: This file contains the implementation of TokenizerHelper.
// This class should be used by most - if not all - MIL parsers.
//
// History:
// 05/19/2003 : Microsoft - Created it
// 05/20/2003 : Microsoft - Moved to Shared
//
//---------------------------------------------------------------------------
using System;
using System.Globalization;
namespace HandyControl.Tools
{
internal class TokenizerHelper
{
private char _quoteChar;
private char _argSeparator;
private string _str;
private int _strLen;
private int _charIndex;
private int _currentTokenIndex;
private int _currentTokenLength;
public bool FoundSeparator { get; private set; }
public TokenizerHelper(string str, IFormatProvider formatProvider)
{
var numberSeparator = GetNumericListSeparator(formatProvider);
Initialize(str, '\'', numberSeparator);
}
private void Initialize(string str, char quoteChar, char separator)
{
_str = str;
_strLen = str?.Length ?? 0;
_currentTokenIndex = -1;
_quoteChar = quoteChar;
_argSeparator = separator;
// immediately forward past any whitespace so
// NextToken() logic always starts on the first
// character of the next token.
while (_charIndex < _strLen)
{
if (!char.IsWhiteSpace(_str, _charIndex))
{
break;
}
++_charIndex;
}
}
public string GetCurrentToken() =>
_currentTokenIndex < 0 ? null : _str.Substring(_currentTokenIndex, _currentTokenLength);
internal bool NextToken() => NextToken(false);
public bool NextToken(bool allowQuotedToken) => NextToken(allowQuotedToken, _argSeparator);
public bool NextToken(bool allowQuotedToken, char separator)
{
_currentTokenIndex = -1; // reset the currentTokenIndex
FoundSeparator = false; // reset
// If we're at end of the string, just return false.
if (_charIndex >= _strLen)
{
return false;
}
var currentChar = _str[_charIndex];
// setup the quoteCount
var quoteCount = 0;
// If we are allowing a quoted token and this token begins with a quote,
// set up the quote count and skip the initial quote
if (allowQuotedToken &&
currentChar == _quoteChar)
{
quoteCount++; // increment quote count
++_charIndex; // move to next character
}
var newTokenIndex = _charIndex;
var newTokenLength = 0;
// loop until hit end of string or hit a , or whitespace
// if at end of string ust return false.
while (_charIndex < _strLen)
{
currentChar = _str[_charIndex];
// if have a QuoteCount and this is a quote
// decrement the quoteCount
if (quoteCount > 0)
{
// if anything but a quoteChar we move on
if (currentChar == _quoteChar)
{
--quoteCount;
// if at zero which it always should for now
// break out of the loop
if (0 == quoteCount)
{
++_charIndex; // move past the quote
break;
}
}
}
else if (char.IsWhiteSpace(currentChar) || currentChar == separator)
{
if (currentChar == separator)
{
FoundSeparator = true;
}
break;
}
++_charIndex;
++newTokenLength;
}
// if quoteCount isn't zero we hit the end of the string
// before the ending quote
if (quoteCount > 0)
{
throw new InvalidOperationException("TokenizerHelperMissingEndQuote");
}
ScanToNextToken(separator); // move so at the start of the nextToken for next call
// finally made it, update the _currentToken values
_currentTokenIndex = newTokenIndex;
_currentTokenLength = newTokenLength;
if (_currentTokenLength < 1)
{
throw new InvalidOperationException("TokenizerHelperEmptyToken");
}
return true;
}
private void ScanToNextToken(char separator)
{
// if already at end of the string don't bother
if (_charIndex >= _strLen) return;
var currentChar = _str[_charIndex];
// check that the currentChar is a space or the separator. If not
// we have an error. this can happen in the quote case
// that the char after the quotes string isn't a char.
if (currentChar != separator && !char.IsWhiteSpace(currentChar))
{
throw new InvalidOperationException("TokenizerHelperExtraDataEncountered");
}
// loop until hit a character that isn't
// an argument separator or whitespace.
// !!!Todo: if more than one argSet throw an exception
var argSepCount = 0;
while (_charIndex < _strLen)
{
currentChar = _str[_charIndex];
if (currentChar == separator)
{
FoundSeparator = true;
++argSepCount;
_charIndex++;
if (argSepCount > 1)
{
throw new InvalidOperationException("TokenizerHelperEmptyToken");
}
}
else if (char.IsWhiteSpace(currentChar))
{
++_charIndex;
}
else
{
break;
}
}
// if there was a separatorChar then we shouldn't be
// at the end of string or means there was a separator
// but there isn't an arg
if (argSepCount > 0 && _charIndex >= _strLen)
{
throw new InvalidOperationException("TokenizerHelperEmptyToken");
}
}
internal static char GetNumericListSeparator(IFormatProvider provider)
{
var numericSeparator = ',';
// Get the NumberFormatInfo out of the provider, if possible
// If the IFormatProvider doesn't not contain a NumberFormatInfo, then
// this method returns the current culture's NumberFormatInfo.
var numberFormat = NumberFormatInfo.GetInstance(provider);
// Is the decimal separator is the same as the list separator?
// If so, we use the ";".
if (numberFormat.NumberDecimalSeparator.Length > 0 && numericSeparator == numberFormat.NumberDecimalSeparator[0])
{
numericSeparator = ';';
}
return numericSeparator;
}
}
}
Loaded 100 of 375 files, more files were not shown because too many files have changed in this diff. Show more