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}]";
}
}