首次提交
This commit is contained in:
132
WpfAppTest/WindowBehavior.cs
Normal file
132
WpfAppTest/WindowBehavior.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user