Merge branch 'master' into master
This commit is contained in:
608 files changed
+11322
-6260
No files matched your search
@@ -37,15 +37,12 @@ namespace HandyControl.Tools.Converter
|
||||
{
|
||||
if (source == null) throw GetConvertFromException(null);
|
||||
|
||||
switch (source)
|
||||
return source switch
|
||||
{
|
||||
case string s:
|
||||
return FromString(s, cultureInfo);
|
||||
case double d:
|
||||
return new ColLayout((int)d);
|
||||
default:
|
||||
return new ColLayout(Convert.ToInt32(source, cultureInfo));
|
||||
}
|
||||
string s => FromString(s, cultureInfo),
|
||||
double d => new ColLayout((int) d),
|
||||
_ => new ColLayout(Convert.ToInt32(source, cultureInfo))
|
||||
};
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
@@ -108,53 +105,31 @@ namespace HandyControl.Tools.Converter
|
||||
i++;
|
||||
}
|
||||
|
||||
switch (i)
|
||||
return i switch
|
||||
{
|
||||
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");
|
||||
1 => new ColLayout(lengths[0]),
|
||||
2 => new ColLayout {Xs = lengths[0], Sm = lengths[1]},
|
||||
3 => new ColLayout {Xs = lengths[0], Sm = lengths[1], Md = lengths[2]},
|
||||
4 => new ColLayout {Xs = lengths[0], Sm = lengths[1], Md = lengths[2], Lg = lengths[3]},
|
||||
5 => new ColLayout
|
||||
{
|
||||
Xs = lengths[0],
|
||||
Sm = lengths[1],
|
||||
Md = lengths[2],
|
||||
Lg = lengths[3],
|
||||
Xl = lengths[4]
|
||||
},
|
||||
6 => 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,16 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace HandyControl.Tools.Converter
|
||||
{
|
||||
public class Object2StringConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => value?.ToString();
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace HandyControl.Tools.Converter
|
||||
{
|
||||
public class Object2VisibilityReConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value == null ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,6 @@ namespace HandyControl.Tools.Extension
|
||||
{
|
||||
private readonly DependencyObject _proxy;
|
||||
|
||||
private bool _isInternalAction;
|
||||
|
||||
public LangExtension()
|
||||
{
|
||||
_proxy = new DependencyObject();
|
||||
@@ -51,7 +49,6 @@ namespace HandyControl.Tools.Extension
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (_isInternalAction) return this;
|
||||
if (!(serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget provideValueTarget)) return this;
|
||||
if (provideValueTarget.TargetObject.GetType().FullName == "System.Windows.SharedDp") return this;
|
||||
if (!(provideValueTarget.TargetObject is DependencyObject targetObject)) return this;
|
||||
@@ -61,14 +58,7 @@ namespace HandyControl.Tools.Extension
|
||||
{
|
||||
case string key:
|
||||
{
|
||||
var binding = new Binding(key)
|
||||
{
|
||||
Converter = Converter,
|
||||
ConverterParameter = ConverterParameter,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
|
||||
Source = Source,
|
||||
Mode = BindingMode.OneWay
|
||||
};
|
||||
var binding = CreateLangBinding(key);
|
||||
BindingOperations.SetBinding(targetObject, targetProperty, binding);
|
||||
return binding.ProvideValue(serviceProvider);
|
||||
}
|
||||
@@ -76,10 +66,8 @@ namespace HandyControl.Tools.Extension
|
||||
{
|
||||
if (element.DataContext != null)
|
||||
{
|
||||
_isInternalAction = true;
|
||||
SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
|
||||
_isInternalAction = false;
|
||||
return element.GetValue(targetProperty);
|
||||
var binding = SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
|
||||
return binding.ProvideValue(serviceProvider);
|
||||
}
|
||||
|
||||
SetTargetProperty(element, targetProperty);
|
||||
@@ -91,10 +79,8 @@ namespace HandyControl.Tools.Extension
|
||||
{
|
||||
if (element.DataContext != null)
|
||||
{
|
||||
_isInternalAction = true;
|
||||
SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
|
||||
_isInternalAction = false;
|
||||
return element.GetValue(targetProperty);
|
||||
var binding = SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
|
||||
return binding.ProvideValue(serviceProvider);
|
||||
}
|
||||
|
||||
SetTargetProperty(element, targetProperty);
|
||||
@@ -134,9 +120,9 @@ namespace HandyControl.Tools.Extension
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLangBinding(DependencyObject targetObject, DependencyProperty targetProperty, PropertyPath path, object dataContext)
|
||||
private BindingBase SetLangBinding(DependencyObject targetObject, DependencyProperty targetProperty, PropertyPath path, object dataContext)
|
||||
{
|
||||
if (targetProperty == null) return;
|
||||
if (targetProperty == null) return null;
|
||||
|
||||
BindingOperations.SetBinding(targetObject, targetProperty, new Binding
|
||||
{
|
||||
@@ -146,16 +132,20 @@ namespace HandyControl.Tools.Extension
|
||||
});
|
||||
|
||||
var key = targetObject.GetValue(targetProperty) as string;
|
||||
if (string.IsNullOrEmpty(key)) return;
|
||||
if (string.IsNullOrEmpty(key)) return null;
|
||||
|
||||
BindingOperations.SetBinding(targetObject, targetProperty, new Binding(key)
|
||||
{
|
||||
Converter = Converter,
|
||||
ConverterParameter = ConverterParameter,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
|
||||
Source = Source,
|
||||
Mode = BindingMode.OneWay
|
||||
});
|
||||
var binding = CreateLangBinding(key);
|
||||
BindingOperations.SetBinding(targetObject, targetProperty, binding);
|
||||
return binding;
|
||||
}
|
||||
|
||||
private BindingBase CreateLangBinding(string key) => new Binding(key)
|
||||
{
|
||||
Converter = Converter,
|
||||
ConverterParameter = ConverterParameter,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
|
||||
Source = Source,
|
||||
Mode = BindingMode.OneWay
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,23 @@
|
||||
using System.Windows;
|
||||
using HandyControl.Expression.Drawing;
|
||||
|
||||
namespace HandyControl.Tools.Extension
|
||||
{
|
||||
public static class ValueExtension
|
||||
{
|
||||
public static Thickness Add(this Thickness a, Thickness b) => new Thickness(a.Left + b.Left, a.Top + b.Top, a.Right + b.Right, a.Bottom + b.Bottom);
|
||||
|
||||
public static bool IsZero(this Thickness thickness) =>
|
||||
MathHelper.IsZero(thickness.Left)
|
||||
&& MathHelper.IsZero(thickness.Top)
|
||||
&& MathHelper.IsZero(thickness.Right)
|
||||
&& MathHelper.IsZero(thickness.Bottom);
|
||||
|
||||
public static bool IsUniform(this Thickness thickness) =>
|
||||
MathHelper.AreClose(thickness.Left, thickness.Top)
|
||||
&& MathHelper.AreClose(thickness.Left, thickness.Right)
|
||||
&& MathHelper.AreClose(thickness.Left, thickness.Bottom);
|
||||
|
||||
public static bool IsNaN(this double value) => double.IsNaN(value);
|
||||
}
|
||||
}
|
||||
@@ -92,10 +92,7 @@ namespace HandyControl.Tools
|
||||
{
|
||||
// Construct the image array
|
||||
//
|
||||
if (ImageInfoList == null)
|
||||
{
|
||||
ImageInfoList = new List<GifImageInfo>();
|
||||
}
|
||||
ImageInfoList ??= new List<GifImageInfo>();
|
||||
|
||||
// Add the new image
|
||||
//
|
||||
@@ -108,7 +105,7 @@ namespace HandyControl.Tools
|
||||
{
|
||||
AnimationThread = new Thread(AnimateImages50Ms)
|
||||
{
|
||||
Name = typeof(ImageAnimator).Name,
|
||||
Name = nameof(ImageAnimator),
|
||||
IsBackground = true
|
||||
};
|
||||
AnimationThread.Start();
|
||||
@@ -168,13 +165,18 @@ namespace HandyControl.Tools
|
||||
|
||||
if (Equals(image, imageInfo.Image))
|
||||
{
|
||||
if ((onFrameChangedHandler == imageInfo.FrameChangedHandler) || (onFrameChangedHandler != null && onFrameChangedHandler.Equals(imageInfo.FrameChangedHandler)))
|
||||
if (onFrameChangedHandler == imageInfo.FrameChangedHandler || onFrameChangedHandler != null && onFrameChangedHandler.Equals(imageInfo.FrameChangedHandler))
|
||||
{
|
||||
ImageInfoList.Remove(imageInfo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ImageInfoList.Any())
|
||||
{
|
||||
AnimationThread = null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -224,7 +226,7 @@ namespace HandyControl.Tools
|
||||
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals")]
|
||||
private static void AnimateImages50Ms()
|
||||
{
|
||||
while (true)
|
||||
while (ImageInfoList.Any())
|
||||
{
|
||||
// Acquire reader-lock to access imageInfoList, elemens in the list can be modified w/o needing a writer-lock.
|
||||
// Observe that we don't need to check if the thread is waiting or a writer lock here since the thread this
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace HandyControl.Tools
|
||||
}
|
||||
|
||||
public static void SetHost(DependencyObject element, bool value)
|
||||
=> element.SetValue(HostProperty, value);
|
||||
=> element.SetValue(HostProperty, ValueBoxes.BooleanBox(value));
|
||||
|
||||
public static bool GetHost(DependencyObject element)
|
||||
=> (bool) element.GetValue(HostProperty);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
#if !netle40
|
||||
#if !NET40
|
||||
using System.Runtime.CompilerServices;
|
||||
#endif
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Navigation;
|
||||
using HandyControl.Controls;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Properties.Langs;
|
||||
|
||||
@@ -38,7 +37,7 @@ namespace HandyControl.Tools
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSystemVersionInfo(SystemVersionInfo info) => BlurWindow.SystemVersionInfo = info;
|
||||
public SystemVersionInfo SystemVersionInfo { get; set; }
|
||||
|
||||
public void SetLang(string lang)
|
||||
{
|
||||
@@ -49,7 +48,7 @@ namespace HandyControl.Tools
|
||||
|
||||
public void SetConfig(HandyControlConfig config)
|
||||
{
|
||||
SetSystemVersionInfo(config.SystemVersionInfo);
|
||||
SystemVersionInfo = config.SystemVersionInfo;
|
||||
SetLang(config.Lang);
|
||||
SetTimelineFrameRate(config.TimelineFrameRate);
|
||||
}
|
||||
@@ -60,10 +59,10 @@ namespace HandyControl.Tools
|
||||
public void SetWindowDefaultStyle(object resourceKey = null)
|
||||
{
|
||||
var metadata = resourceKey == null
|
||||
? new FrameworkPropertyMetadata(Application.Current.FindResource(typeof(System.Windows.Window)))
|
||||
? new FrameworkPropertyMetadata(Application.Current.FindResource(typeof(Window)))
|
||||
: new FrameworkPropertyMetadata(Application.Current.FindResource(resourceKey));
|
||||
|
||||
FrameworkElement.StyleProperty.OverrideMetadata(typeof(System.Windows.Window), metadata);
|
||||
FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), metadata);
|
||||
}
|
||||
|
||||
public void SetNavigationWindowDefaultStyle(object resourceKey = null)
|
||||
@@ -77,7 +76,7 @@ namespace HandyControl.Tools
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
#if netle40
|
||||
#if NET40
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using HandyControl.Expression.Drawing;
|
||||
using HandyControl.Tools.Interop;
|
||||
|
||||
namespace HandyControl.Tools
|
||||
@@ -17,8 +18,12 @@ namespace HandyControl.Tools
|
||||
var dC = InteropMethods.GetDC(IntPtr.Zero);
|
||||
if (dC != IntPtr.Zero)
|
||||
{
|
||||
DeviceDpiX = InteropMethods.GetDeviceCaps(dC, 88);
|
||||
DeviceDpiY = InteropMethods.GetDeviceCaps(dC, 90);
|
||||
// 沿着屏幕宽度每逻辑英寸的像素数。在具有多个显示器的系统中,这个值对所有显示器都是相同的
|
||||
const int logicPixelsX = 88;
|
||||
// 沿着屏幕高度每逻辑英寸的像素数
|
||||
const int logicPixelsY = 90;
|
||||
DeviceDpiX = InteropMethods.GetDeviceCaps(dC, logicPixelsX);
|
||||
DeviceDpiY = InteropMethods.GetDeviceCaps(dC, logicPixelsY);
|
||||
InteropMethods.ReleaseDC(IntPtr.Zero, dC);
|
||||
}
|
||||
else
|
||||
@@ -75,5 +80,25 @@ namespace HandyControl.Tools
|
||||
result.Transform(TransformFromDevice.Matrix);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double RoundLayoutValue(double value, double dpiScale)
|
||||
{
|
||||
double newValue;
|
||||
|
||||
if (!MathHelper.AreClose(dpiScale, 1.0))
|
||||
{
|
||||
newValue = Math.Round(value * dpiScale) / dpiScale;
|
||||
if (double.IsNaN(newValue) || double.IsInfinity(newValue) || MathHelper.AreClose(newValue, double.MaxValue))
|
||||
{
|
||||
newValue = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = Math.Round(value);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HandyControl.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// 输入层点击帮助类
|
||||
/// </summary>
|
||||
public static class InputClickHelper
|
||||
{
|
||||
private static readonly DependencyProperty InputInfoProperty = DependencyProperty.RegisterAttached(
|
||||
"InputInfo", typeof(InputInfo), typeof(InputClickHelper), new PropertyMetadata(default(InputInfo)));
|
||||
|
||||
private static void SetInputInfo(DependencyObject element, InputInfo value) => element.SetValue(InputInfoProperty, value);
|
||||
|
||||
private static InputInfo GetInputInfo(DependencyObject element) => (InputInfo)element.GetValue(InputInfoProperty);
|
||||
|
||||
/// <summary>
|
||||
/// 将 MouseDown MouseMove MouseUp 封装为点击事件
|
||||
/// </summary>
|
||||
/// <param name="element">要被附加的元素</param>
|
||||
/// <param name="clickEventHandler">点击的事件</param>
|
||||
/// <param name="dragStarted">因为拖动而结束点击时触发</param>
|
||||
public static void AttachMouseDownMoveUpToClick(UIElement element, EventHandler clickEventHandler,
|
||||
EventHandler dragStarted = null)
|
||||
{
|
||||
var inputInfo = GetOrCreateInputInfo(element);
|
||||
inputInfo.ClickEventHandler += clickEventHandler;
|
||||
|
||||
inputInfo.DragStarted += dragStarted;
|
||||
|
||||
element.MouseDown -= Element_MouseDown;
|
||||
element.MouseDown += Element_MouseDown;
|
||||
element.MouseMove -= Element_MouseMove;
|
||||
element.MouseMove += Element_MouseMove;
|
||||
element.MouseUp -= Element_MouseUp;
|
||||
element.MouseUp += Element_MouseUp;
|
||||
element.LostMouseCapture -= Element_LostMouseCapture;
|
||||
element.LostMouseCapture += Element_LostMouseCapture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 去掉对 <paramref name="element" /> 的点击时间的监听
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
/// <param name="clickEventHandler">点击的事件</param>
|
||||
/// <param name="dragStarted">因为拖动而结束点击时触发的事件</param>
|
||||
public static void DetachMouseDownMoveUpToClick(UIElement element, EventHandler clickEventHandler,
|
||||
EventHandler dragStarted = null)
|
||||
{
|
||||
var inputInfo = GetInputInfo(element);
|
||||
if (inputInfo == null) return;
|
||||
|
||||
inputInfo.ClickEventHandler -= clickEventHandler;
|
||||
inputInfo.DragStarted -= dragStarted;
|
||||
|
||||
if (inputInfo.IsEmpty())
|
||||
{
|
||||
element.ClearValue(InputInfoProperty);
|
||||
element.MouseDown -= Element_MouseDown;
|
||||
element.MouseMove -= Element_MouseMove;
|
||||
element.MouseUp -= Element_MouseUp;
|
||||
element.LostMouseCapture -= Element_LostMouseCapture;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Element_LostMouseCapture(object sender, MouseEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
GetInputInfo(element)?.LostCapture();
|
||||
}
|
||||
|
||||
private static void Element_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
GetInputInfo(element)?.Up(e.GetPosition(element));
|
||||
}
|
||||
|
||||
private static void Element_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
GetInputInfo(element)?.Move(e.GetPosition(element));
|
||||
}
|
||||
|
||||
private static void Element_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
GetInputInfo(element)?.Down(e.GetPosition(element));
|
||||
}
|
||||
|
||||
private static InputInfo GetOrCreateInputInfo(UIElement element)
|
||||
{
|
||||
var inputInfo = GetInputInfo(element);
|
||||
if (inputInfo == null)
|
||||
{
|
||||
inputInfo = new InputInfo();
|
||||
SetInputInfo(element, inputInfo);
|
||||
}
|
||||
|
||||
return inputInfo;
|
||||
}
|
||||
|
||||
private class InputInfo
|
||||
{
|
||||
private const double ToleranceSquared = 0.01;
|
||||
|
||||
private Point _downedPosition;
|
||||
|
||||
private bool _isClick;
|
||||
|
||||
public event EventHandler ClickEventHandler;
|
||||
|
||||
public event EventHandler DragStarted;
|
||||
|
||||
public void Down(Point position)
|
||||
{
|
||||
_downedPosition = position;
|
||||
_isClick = true;
|
||||
}
|
||||
|
||||
public void Move(Point position)
|
||||
{
|
||||
if (!_isClick) return;
|
||||
|
||||
if ((position - _downedPosition).LengthSquared > ToleranceSquared)
|
||||
{
|
||||
_isClick = false;
|
||||
DragStarted?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public void Up(Point position)
|
||||
{
|
||||
_isClick = _isClick && (position - _downedPosition).LengthSquared <= ToleranceSquared;
|
||||
|
||||
if (!_isClick) return;
|
||||
|
||||
ClickEventHandler?.Invoke(null, EventArgs.Empty);
|
||||
|
||||
_isClick = false;
|
||||
}
|
||||
|
||||
public void LostCapture() => _isClick = false;
|
||||
|
||||
public bool IsEmpty() => ClickEventHandler is null && DragStarted is null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ namespace HandyControl.Tools
|
||||
|
||||
public static T GetChild<T>(DependencyObject d) where T : DependencyObject
|
||||
{
|
||||
if (d == null) return default;
|
||||
if (d is T t) return t;
|
||||
|
||||
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)
|
||||
|
||||
@@ -132,15 +132,17 @@ namespace HandyControl.Tools
|
||||
{
|
||||
get
|
||||
{
|
||||
#if netle40
|
||||
return WindowResizeBorderThickness;
|
||||
InteropValues.APPBARDATA appBarData = default;
|
||||
var autoHide = InteropMethods.SHAppBarMessage(4, ref appBarData) != 0;
|
||||
#if NET40
|
||||
return WindowResizeBorderThickness.Add(new Thickness(autoHide ? -8 : 0));
|
||||
#elif Core
|
||||
var hdc = InteropMethods.GetDC(IntPtr.Zero);
|
||||
var scale = InteropMethods.GetDeviceCaps(hdc, InteropValues.DESKTOPVERTRES) / (float)InteropMethods.GetDeviceCaps(hdc, InteropValues.VERTRES);
|
||||
InteropMethods.ReleaseDC(IntPtr.Zero, hdc);
|
||||
return WindowResizeBorderThickness.Add(new Thickness(4 * scale));
|
||||
return WindowResizeBorderThickness.Add(new Thickness((autoHide ? - 4 : 4) * scale));
|
||||
#else
|
||||
return WindowResizeBorderThickness.Add(new Thickness(4));
|
||||
return WindowResizeBorderThickness.Add(new Thickness(autoHide ? - 4 : 4));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace HandyControl.Tools.Interop
|
||||
{
|
||||
#region common
|
||||
|
||||
public const int E_FAIL = unchecked((int)0x80004005);
|
||||
internal const int E_FAIL = unchecked((int)0x80004005);
|
||||
|
||||
internal static readonly IntPtr HRGN_NONE = new IntPtr(-1);
|
||||
|
||||
@@ -461,7 +461,10 @@ namespace HandyControl.Tools.Interop
|
||||
|
||||
[ReflectionPermission(SecurityAction.Assert, Unrestricted = true),
|
||||
SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
|
||||
public static void PtrToStructure(IntPtr lparam, object data) => Marshal.PtrToStructure(lparam, data);
|
||||
internal static void PtrToStructure(IntPtr lparam, object data) => Marshal.PtrToStructure(lparam, data);
|
||||
|
||||
[DllImport(InteropValues.ExternDll.Shell32, CallingConvention = CallingConvention.StdCall)]
|
||||
internal static extern uint SHAppBarMessage(int dwMessage, ref InteropValues.APPBARDATA pData);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace HandyControl.Tools.Interop
|
||||
NIIF_ERROR = 0x00000003,
|
||||
WM_ACTIVATE = 0x0006,
|
||||
WM_QUIT = 0x0012,
|
||||
WM_GETMINMAXINFO = 0x0024,
|
||||
WM_WINDOWPOSCHANGING = 0x0046,
|
||||
WM_WINDOWPOSCHANGED = 0x0047,
|
||||
WM_SETICON = 0x0080,
|
||||
@@ -85,7 +86,8 @@ namespace HandyControl.Tools.Interop
|
||||
SC_MINIMIZE = 0xF020,
|
||||
SC_MAXIMIZE = 0xF030,
|
||||
SC_RESTORE = 0xF120,
|
||||
SRCCOPY = 0x00CC0020;
|
||||
SRCCOPY = 0x00CC0020,
|
||||
MONITOR_DEFAULTTONEAREST = 0x00000002;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
internal class NOTIFYICONDATA
|
||||
@@ -933,5 +935,26 @@ namespace HandyControl.Tools.Interop
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class MINMAXINFO
|
||||
{
|
||||
public POINT ptReserved;
|
||||
public POINT ptMaxSize;
|
||||
public POINT ptMaxPosition;
|
||||
public POINT ptMinTrackSize;
|
||||
public POINT ptMaxTrackSize;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct APPBARDATA
|
||||
{
|
||||
public int cbSize;
|
||||
public IntPtr hWnd;
|
||||
public uint uCallbackMessage;
|
||||
public uint uEdge;
|
||||
public RECT rc;
|
||||
public int lParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,18 +66,9 @@ namespace HandyControl.Tools
|
||||
public Deque(IEnumerable<T> backCollection, IEnumerable<T> frontCollection)
|
||||
{
|
||||
if (backCollection == null && frontCollection == null) throw new ArgumentException("Collections cannot both be null");
|
||||
_front = new List<T>();
|
||||
_back = new List<T>();
|
||||
|
||||
if (backCollection != null)
|
||||
{
|
||||
foreach (var item in backCollection) _back.Add(item);
|
||||
}
|
||||
|
||||
if (frontCollection != null)
|
||||
{
|
||||
foreach (var item in frontCollection) _front.Add(item);
|
||||
}
|
||||
_front = frontCollection != null ? new List<T>(frontCollection) : new List<T>();
|
||||
_back = backCollection != null ? new List<T>(backCollection) : new List<T>();
|
||||
}
|
||||
|
||||
public void AddFirst(T item)
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using HandyControl.Data;
|
||||
|
||||
namespace HandyControl.Tools
|
||||
{
|
||||
public class ComboBoxItemCapsuleStyleSelector : StyleSelector
|
||||
{
|
||||
public override Style SelectStyle(object item, DependencyObject container)
|
||||
{
|
||||
if (container is ComboBoxItem comboBoxItem && VisualHelper.GetParent<ComboBox>(comboBoxItem) is { } comboBox)
|
||||
{
|
||||
var count = comboBox.Items.Count;
|
||||
if (count == 1)
|
||||
{
|
||||
return ResourceHelper.GetResource<Style>(ResourceToken.ComboBoxItemCapsuleSingle);
|
||||
}
|
||||
|
||||
var index = comboBox.ItemContainerGenerator.IndexFromContainer(comboBoxItem);
|
||||
return index == 0
|
||||
? ResourceHelper.GetResource<Style>(ResourceToken.ComboBoxItemCapsuleHorizontalFirst)
|
||||
: ResourceHelper.GetResource<Style>(index == count - 1
|
||||
? ResourceToken.ComboBoxItemCapsuleHorizontalLast
|
||||
: ResourceToken.ComboBoxItemCapsuleDefault);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace HandyControl.Tools
|
||||
{
|
||||
public override Style SelectStyle(object item, DependencyObject container)
|
||||
{
|
||||
if (item is TabItem tabItem && tabItem.Parent is TabControl tabControl)
|
||||
if (container is TabItem tabItem && VisualHelper.GetParent<TabControl>(tabItem) is { } tabControl)
|
||||
{
|
||||
var count = tabControl.Items.Count;
|
||||
if (count == 1)
|
||||
@@ -16,7 +16,7 @@ namespace HandyControl.Tools
|
||||
return ResourceHelper.GetResource<Style>(ResourceToken.TabItemCapsuleSingle);
|
||||
}
|
||||
|
||||
var index = tabControl.Items.IndexOf(tabItem);
|
||||
var index = tabControl.ItemContainerGenerator.IndexFromContainer(tabItem);
|
||||
return index == 0
|
||||
? ResourceHelper.GetResource<Style>(
|
||||
tabControl.TabStripPlacement == Dock.Top || tabControl.TabStripPlacement == Dock.Bottom
|
||||
|
||||
Reference in new issue
Block a user