using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace HKW.HKWUtils; /// /// 拓展 /// public static class Extensions { /// /// /// /// /// /// /// public static bool Contains(this string source, string value, StringComparison comparisonType) { return source.IndexOf(value, comparisonType) >= 0; } //public static string GetSourceFile(this BitmapImage image) //{ // return ((FileStream)image.StreamSource).Name; //} /// /// 关闭流 /// /// 图像资源 public static void CloseStream(this ImageSource source) { if (source is not BitmapImage image) return; image.StreamSource?.Close(); } /// /// 图像复制 /// /// 图像 /// 复制的图像 public static BitmapImage Copy(this BitmapImage image) { if (image is null) return null; BitmapImage newImage = new(); newImage.BeginInit(); newImage.DecodePixelWidth = image.DecodePixelWidth; newImage.DecodePixelHeight = image.DecodePixelHeight; try { using var bitmap = new Bitmap(image.StreamSource); var ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); image.StreamSource.CopyTo(ms); newImage.StreamSource = ms; } finally { newImage.EndInit(); } return newImage; } /// /// 保存至Png图片 /// /// 图片资源 /// 路径 //public static void SaveToPng(this BitmapImage image, string path) //{ // if (image is null) // return; // if (path.EndsWith(".png") is false) // path += ".png"; // var encoder = new PngBitmapEncoder(); // var stream = image.StreamSource; // // 保存位置 // var position = stream.Position; // // 必须要重置位置, 否则EndInit将出错 // stream.Seek(0, SeekOrigin.Begin); // encoder.Frames.Add(BitmapFrame.Create(image.StreamSource)); // // 恢复位置 // stream.Seek(position, SeekOrigin.Begin); // using var fs = new FileStream(path, FileMode.Create); // encoder.Save(fs); //} public static void SaveToPng(this BitmapImage image, string path) { if (image is null) return; if (path.EndsWith(".png") is false) path += ".png"; var stream = image.StreamSource; // 保存位置 var position = stream.Position; // 必须要重置位置, 否则EndInit将出错 stream.Seek(0, SeekOrigin.Begin); using var fs = new FileStream(path, FileMode.Create); stream.CopyTo(fs); // 恢复位置 stream.Seek(position, SeekOrigin.Begin); } /// /// 尝试添加 /// /// 键类型 /// /// /// 键 /// 值 /// 成功为 失败为 public static bool TryAdd( this IDictionary dictionary, TKey key, TValue value ) { if (dictionary.ContainsKey(key)) return false; dictionary.Add(key, value); return true; } /// /// 流内容对比 /// /// 原始流 /// 目标流 /// 缓冲区大小 (越大速度越快(流内容越大效果越明显), 但会提高内存占用 (bufferSize = bufferLength * sizeof(long) * 2)) /// 内容相同为 否则为 public static bool ContentsEqual(this Stream source, Stream target, int bufferLength = 8) { int bufferSize = bufferLength * sizeof(long); var sourceBuffer = new byte[bufferSize]; var targetBuffer = new byte[bufferSize]; while (true) { int sourceCount = ReadFullBuffer(source, sourceBuffer); int targetCount = ReadFullBuffer(target, targetBuffer); if (sourceCount != targetCount) return false; if (sourceCount == 0) return true; for (int i = 0; i < sourceCount; i += sizeof(long)) if (BitConverter.ToInt64(sourceBuffer, i) != BitConverter.ToInt64(targetBuffer, i)) return false; } static int ReadFullBuffer(Stream stream, byte[] buffer) { int bytesRead = 0; while (bytesRead < buffer.Length) { int read = stream.Read(buffer, bytesRead, buffer.Length - bytesRead); if (read == 0) return bytesRead; bytesRead += read; } return bytesRead; } } public static T? FindVisualChild(this DependencyObject obj) where T : DependencyObject { if (obj is null) return null; var count = VisualTreeHelper.GetChildrenCount(obj); for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(obj, i); if (child is T t) return t; if (FindVisualChild(child) is T childItem) return childItem; } return null; } public static T FindParent(this DependencyObject obj) where T : class { while (obj != null) { if (obj is T) return obj as T; obj = VisualTreeHelper.GetParent(obj); } return null; } public static string GetFullInfo(this CultureInfo cultureInfo) { return $"{cultureInfo.DisplayName} [{cultureInfo.Name}]"; } /// /// 尝试使用索引获取值 /// /// 值类型 /// 列表 /// 索引 /// 值 /// 成功为 失败为 public static bool TryGetValue(this IList list, int index, out T value) { value = default; if (index < 0 || index >= list.Count) return false; value = list[index]; return true; } /// /// 尝试使用索引获取值 /// /// 值类型 /// 列表 /// 索引 /// 值 /// 成功为 失败为 public static bool TryGetValue(this IList list, int index, out object value) { value = default; if (index < 0 || index >= list.Count) return false; value = list[index]; return true; } /// /// 获取目标 /// /// 类型 /// 弱引用 /// 获取成功返回目标值, 获取失败则返回 public static T? GetTarget(this WeakReference weakReference) where T : class { return weakReference.TryGetTarget(out var t) ? t : null; } /// /// 枚举出带有索引值的枚举值 /// /// 值类型 /// 集合 /// 带有索引的枚举值 public static IEnumerable> Enumerate(this IEnumerable collection) { var index = 0; foreach (var item in collection) yield return new(index++, item); } /// /// 设置视图模型 /// /// 视图模型类型 /// 窗口 public static T SetViewModel(this Window window, EventHandler? closedEvent = null) where T : new() { if (window.DataContext is null) { window.DataContext = new T(); window.Closed += (s, e) => { try { window.DataContext = null; } catch { } }; window.Closed += closedEvent; } return (T)window.DataContext; } /// /// 设置视图模型 /// /// 视图模型类型 /// 页面 public static T SetViewModel(this Page page) where T : new() { return (T)(page.DataContext ??= new T()); } private static Dictionary _windowCloseStates = new(); /// /// 设置关闭状态 /// /// /// 关闭状态 public static void SetCloseState(this Window window, WindowCloseState state) { window.Closing -= WindowCloseState_Closing; window.Closing += WindowCloseState_Closing; _windowCloseStates[window] = state; } /// /// 强制关闭 /// /// public static void CloseX(this Window? window) { if (window is null) return; _windowCloseStates.Remove(window); window.Closing -= WindowCloseState_Closing; window.Close(); } /// /// 显示或者聚焦 /// /// public static void ShowOrActivate(this Window? window) { if (window is null) return; if (window.IsVisible is false) window.Show(); window.Activate(); } private static void WindowCloseState_Closing(object? sender, CancelEventArgs e) { if (sender is not Window window) return; if (_windowCloseStates.TryGetValue(window, out var state) is false) return; if (state.HasFlag(WindowCloseState.SkipNext)) { _windowCloseStates[window] = state &= WindowCloseState.SkipNext; return; } if (state is WindowCloseState.Close) return; e.Cancel = true; window.Visibility = state is WindowCloseState.Hidden ? Visibility.Hidden : Visibility.Collapsed; return; } } [Flags] public enum WindowCloseState { Close = 1 << 0, SkipNext = 1 << 1, Hidden = 1 << 2, Collapsed = 1 << 3 } /// /// 项信息 /// /// [DebuggerDisplay("[{Index}, {Value}]")] public readonly struct ItemInfo { /// /// 索引值 /// public int Index { get; } /// /// 值 /// public T Value { get; } /// /// 值 /// 索引值 public ItemInfo(int index, T value) { Index = index; Value = value; } /// public override string ToString() { return $"[{Index}, {Value}]"; } }