133 lines
5.6 KiB
C#
133 lines
5.6 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Runtime.InteropServices;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
using System.Windows.Interop;
|
|||
|
|
|
|||
|
|
namespace WpfAppTest.Behavior
|
|||
|
|
{
|
|||
|
|
public static class WindowBehavior
|
|||
|
|
{
|
|||
|
|
// 这是我们的附加属性,用于启用自定义窗口行为
|
|||
|
|
public static readonly DependencyProperty EnableCustomWindowBehaviorProperty =
|
|||
|
|
DependencyProperty.RegisterAttached(
|
|||
|
|
"EnableCustomWindowBehavior",
|
|||
|
|
typeof(bool),
|
|||
|
|
typeof(WindowBehavior),
|
|||
|
|
new PropertyMetadata(false, OnEnableCustomWindowBehaviorChanged));
|
|||
|
|
|
|||
|
|
public static bool GetEnableCustomWindowBehavior(DependencyObject obj)
|
|||
|
|
{
|
|||
|
|
return (bool)obj.GetValue(EnableCustomWindowBehaviorProperty);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static void SetEnableCustomWindowBehavior(DependencyObject obj, bool value)
|
|||
|
|
{
|
|||
|
|
obj.SetValue(EnableCustomWindowBehaviorProperty, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 当 EnableCustomWindowBehavior 属性值改变时触发
|
|||
|
|
private static void OnEnableCustomWindowBehaviorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (d is Window window)
|
|||
|
|
{
|
|||
|
|
if ((bool)e.NewValue)
|
|||
|
|
{
|
|||
|
|
// 当启用行为时,在窗口加载后查找并绑定元素
|
|||
|
|
window.Loaded += Window_Loaded;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 当禁用行为时,解除绑定(如果需要更彻底的清理,可以做更多操作)
|
|||
|
|
window.Loaded -= Window_Loaded;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 窗口加载后执行,此时 ControlTemplate 已经被应用
|
|||
|
|
private static void Window_Loaded(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (sender is Window window)
|
|||
|
|
{
|
|||
|
|
// *** 关键:通过 FindName 在 ControlTemplate 中查找元素 ***
|
|||
|
|
// 这些元素的 x:Name 必须与你的 Window 样式模板中的名称一致!
|
|||
|
|
Button minimizeButton = window.Template.FindName("MinimizeButton", window) as Button;
|
|||
|
|
Button maximizeRestoreButton = window.Template.FindName("MaximizeRestoreButton", window) as Button;
|
|||
|
|
Button closeButton = window.Template.FindName("CloseButton", window) as Button;
|
|||
|
|
Border titleBarDragArea = window.Template.FindName("WindowBorder", window) as Border; // 或者你的标题栏 Border 的 x:Name
|
|||
|
|
Border resizeGrip = window.Template.FindName("PART_ResizeGrip", window) as Border; // 调整大小手柄
|
|||
|
|
|
|||
|
|
// --- 绑定按钮点击事件 ---
|
|||
|
|
if (minimizeButton != null)
|
|||
|
|
{
|
|||
|
|
minimizeButton.Click += (s, ev) => window.WindowState = WindowState.Minimized;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (maximizeRestoreButton != null)
|
|||
|
|
{
|
|||
|
|
maximizeRestoreButton.Click += (s, ev) =>
|
|||
|
|
{
|
|||
|
|
if (window.WindowState == WindowState.Normal)
|
|||
|
|
window.WindowState = WindowState.Maximized;
|
|||
|
|
else
|
|||
|
|
window.WindowState = WindowState.Normal;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (closeButton != null)
|
|||
|
|
{
|
|||
|
|
closeButton.Click += (s, ev) => window.Close();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 绑定标题栏拖拽和双击最大化事件 ---
|
|||
|
|
if (titleBarDragArea != null)
|
|||
|
|
{
|
|||
|
|
// 单击并拖动以移动窗口
|
|||
|
|
titleBarDragArea.MouseLeftButtonDown += (s, ev) =>
|
|||
|
|
{
|
|||
|
|
if (ev.ClickCount == 1 && window.WindowState == WindowState.Normal)
|
|||
|
|
{
|
|||
|
|
window.DragMove(); // WPF 内置的拖动方法
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 双击标题栏最大化/还原窗口
|
|||
|
|
titleBarDragArea.MouseLeftButtonDown += (s, ev) =>
|
|||
|
|
{
|
|||
|
|
if (ev.ClickCount == 2)
|
|||
|
|
{
|
|||
|
|
if (window.WindowState == WindowState.Normal)
|
|||
|
|
window.WindowState = WindowState.Maximized;
|
|||
|
|
else
|
|||
|
|
window.WindowState = WindowState.Normal;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 处理调整大小手柄 ---
|
|||
|
|
if (resizeGrip != null)
|
|||
|
|
{
|
|||
|
|
resizeGrip.PreviewMouseLeftButtonDown += (s, ev) =>
|
|||
|
|
{
|
|||
|
|
if (window.WindowState == WindowState.Normal)
|
|||
|
|
{
|
|||
|
|
// 调用 Win32 API 来启动窗口调整大小
|
|||
|
|
IntPtr handle = new WindowInteropHelper(window).Handle;
|
|||
|
|
SendMessage(handle, 0x0112, (IntPtr)0xF008, IntPtr.Zero); // WM_SYSCOMMAND, SC_SIZE (bottom-right)
|
|||
|
|
ev.Handled = true; // 阻止事件冒泡,避免与窗口拖动冲突
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- P/Invoke: 调用 Windows API 的 SendMessage 函数 ---
|
|||
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|||
|
|
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
|||
|
|
}
|
|||
|
|
}
|