WPF에서 모달 대화 상자를 작성 중입니다. 닫기 버튼이 없도록 WPF 창을 어떻게 설정합니까? 나는 여전히 WindowState
일반적인 제목 표시 줄을 갖고 싶습니다 .
내가 발견 ResizeMode
, WindowState
그리고 WindowStyle
하지만 이러한 속성 중 어느 것도 나를 닫기 버튼을 숨길 수 없지만 모달 대화 상자에서 같은 제목 표시 줄을 보여줍니다.
답변
WPF에는 제목 표시 줄의 닫기 단추를 숨길 수있는 기본 제공 속성이 없지만 몇 줄의 P / Invoke를 사용하여 수행 할 수 있습니다.
먼저 다음 선언을 Window 클래스에 추가하십시오.
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
그런 다음이 코드를 Window Loaded
이벤트 에 넣으십시오 .
var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
더 이상 닫기 버튼이 없습니다. 또한 제목 표시 줄 왼쪽에 창 아이콘이 없으므로 제목 표시 줄을 마우스 오른쪽 버튼으로 클릭해도 시스템 메뉴가 없습니다.
참고 Alt+ F4것이다 여전히 창을 닫습니다. 백그라운드 스레드가 완료되기 전에 창을 닫지 않으려면 Gabe가 제안한대로 재정의 OnClosing
하고 Cancel
true로 설정할 수도 있습니다 .
답변
방금 비슷한 문제가 발생하여 Joe White의 솔루션 이 간단하고 깨끗해 보입니다. 재사용하고 Window의 연결된 속성으로 정의했습니다.
public class WindowBehavior
{
private static readonly Type OwnerType = typeof (WindowBehavior);
#region HideCloseButton (attached property)
public static readonly DependencyProperty HideCloseButtonProperty =
DependencyProperty.RegisterAttached(
"HideCloseButton",
typeof (bool),
OwnerType,
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(HideCloseButtonChangedCallback)));
[AttachedPropertyBrowsableForType(typeof(Window))]
public static bool GetHideCloseButton(Window obj) {
return (bool)obj.GetValue(HideCloseButtonProperty);
}
[AttachedPropertyBrowsableForType(typeof(Window))]
public static void SetHideCloseButton(Window obj, bool value) {
obj.SetValue(HideCloseButtonProperty, value);
}
private static void HideCloseButtonChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window == null) return;
var hideCloseButton = (bool)e.NewValue;
if (hideCloseButton && !GetIsHiddenCloseButton(window)) {
if (!window.IsLoaded) {
window.Loaded += HideWhenLoadedDelegate;
}
else {
HideCloseButton(window);
}
SetIsHiddenCloseButton(window, true);
}
else if (!hideCloseButton && GetIsHiddenCloseButton(window)) {
if (!window.IsLoaded) {
window.Loaded -= ShowWhenLoadedDelegate;
}
else {
ShowCloseButton(window);
}
SetIsHiddenCloseButton(window, false);
}
}
#region Win32 imports
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
#endregion
private static readonly RoutedEventHandler HideWhenLoadedDelegate = (sender, args) => {
if (sender is Window == false) return;
var w = (Window)sender;
HideCloseButton(w);
w.Loaded -= HideWhenLoadedDelegate;
};
private static readonly RoutedEventHandler ShowWhenLoadedDelegate = (sender, args) => {
if (sender is Window == false) return;
var w = (Window)sender;
ShowCloseButton(w);
w.Loaded -= ShowWhenLoadedDelegate;
};
private static void HideCloseButton(Window w) {
var hwnd = new WindowInteropHelper(w).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
private static void ShowCloseButton(Window w) {
var hwnd = new WindowInteropHelper(w).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
}
#endregion
#region IsHiddenCloseButton (readonly attached property)
private static readonly DependencyPropertyKey IsHiddenCloseButtonKey =
DependencyProperty.RegisterAttachedReadOnly(
"IsHiddenCloseButton",
typeof (bool),
OwnerType,
new FrameworkPropertyMetadata(false));
public static readonly DependencyProperty IsHiddenCloseButtonProperty =
IsHiddenCloseButtonKey.DependencyProperty;
[AttachedPropertyBrowsableForType(typeof(Window))]
public static bool GetIsHiddenCloseButton(Window obj) {
return (bool)obj.GetValue(IsHiddenCloseButtonProperty);
}
private static void SetIsHiddenCloseButton(Window obj, bool value) {
obj.SetValue(IsHiddenCloseButtonKey, value);
}
#endregion
}
그런 다음 XAML에서 다음과 같이 설정했습니다.
<Window
x:Class="WafClient.Presentation.Views.SampleWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="clr-namespace:WafClient.Presentation.Behaviors"
ResizeMode="NoResize"
u:WindowBehavior.HideCloseButton="True">
...
</Window>
답변
WindowStyle
속성을 없음으로 설정 하면 제목 표시 줄과 함께 컨트롤 상자가 숨겨집니다. 전화를 걸 필요가 없습니다.
답변
이것은 닫기 버튼을 제거하지는 않지만 누군가가 창을 닫는 것을 막을 것입니다.
이것을 코드 뒤에 파일 뒤에 넣으십시오.
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
e.Cancel = true;
}
답변
닫기 버튼을 비활성화하려면 Window 클래스에 다음 코드를 추가해야합니다 (코드는 여기 에서 가져 와서 약간 편집 및 재 포맷).
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
hwndSource.AddHook(HwndSourceHook);
}
}
private bool allowClosing = false;
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
private const uint MF_BYCOMMAND = 0x00000000;
private const uint MF_GRAYED = 0x00000001;
private const uint SC_CLOSE = 0xF060;
private const int WM_SHOWWINDOW = 0x00000018;
private const int WM_CLOSE = 0x10;
private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_SHOWWINDOW:
{
IntPtr hMenu = GetSystemMenu(hwnd, false);
if (hMenu != IntPtr.Zero)
{
EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
}
}
break;
case WM_CLOSE:
if (!allowClosing)
{
handled = true;
}
break;
}
return IntPtr.Zero;
}
이 코드는 또한 시스템 메뉴에서 항목 닫기를 비활성화하고 Alt + F4를 사용하여 대화 상자를 닫을 수 없습니다.
프로그래밍 방식으로 창을 닫고 싶을 것입니다. 전화 Close()
만으로는 효과가 없습니다. 다음과 같이하십시오 :
allowClosing = true;
Close();
답변
나는 버튼을 제거하지 않고 비활성화하는 아이디어를 좋아했기 때문에 Viachaslau의 대답을 시도했지만 어떤 이유로 든 항상 작동하지는 않았습니다. 닫기 버튼은 여전히 활성화되었지만 오류는 없습니다.
반면에 이것은 항상 작동했습니다 (오류 검사 생략).
[DllImport( "user32.dll" )]
private static extern IntPtr GetSystemMenu( IntPtr hWnd, bool bRevert );
[DllImport( "user32.dll" )]
private static extern bool EnableMenuItem( IntPtr hMenu, uint uIDEnableItem, uint uEnable );
private const uint MF_BYCOMMAND = 0x00000000;
private const uint MF_GRAYED = 0x00000001;
private const uint SC_CLOSE = 0xF060;
private const int WM_SHOWWINDOW = 0x00000018;
protected override void OnSourceInitialized( EventArgs e )
{
base.OnSourceInitialized( e );
var hWnd = new WindowInteropHelper( this );
var sysMenu = GetSystemMenu( hWnd.Handle, false );
EnableMenuItem( sysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );
}
답변
설정할 속성은 =>입니다. WindowStyle="None"
<Window x:Class="mdaframework.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Start" Height="350" Width="525" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None">