我正在WPF中写一个模态对话框。我如何设置一个WPF窗口没有关闭按钮?我仍然希望它的WindowState有一个正常的标题栏。
我找到了ResizeMode、WindowState和WindowStyle,但这些属性都不允许我隐藏关闭按钮,而是显示标题栏,就像在模态对话框中一样。
我正在WPF中写一个模态对话框。我如何设置一个WPF窗口没有关闭按钮?我仍然希望它的WindowState有一个正常的标题栏。
我找到了ResizeMode、WindowState和WindowStyle,但这些属性都不允许我隐藏关闭按钮,而是显示标题栏,就像在模态对话框中一样。
当前回答
使用WindowStyle="SingleBorderWindow",这将隐藏WPF窗口的最大和最小按钮。
其他回答
尝试在窗口中添加关闭事件。将此代码添加到事件处理程序中。
e.Cancel = true;
这样可以防止窗口关闭。这与隐藏关闭按钮具有相同的效果。
我只是使用交互性行为(你需要引用System.Windows.Interactivity)添加了我对Joe White的答案的实现。
代码:
public class HideCloseButtonOnWindow : Behavior<Window>
{
#region bunch of native methods
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
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += OnLoaded;
}
protected override void OnDetaching()
{
AssociatedObject.Loaded -= OnLoaded;
base.OnDetaching();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
var hwnd = new WindowInteropHelper(AssociatedObject).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
}
用法:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:w="clr-namespace:WpfApplication2">
<i:Interaction.Behaviors>
<w:HideCloseButtonOnWindow />
</i:Interaction.Behaviors>
</Window>
下面是我如何实现类似的目标使用自定义样式没有DllImports和P/Invoke调用。这删除现有的标题栏使用WindowStyle="none",并显示一个'TextBlock'与类似的背景颜色表明作为标题栏。
XAML 代码
<Window x:Class="AddBook"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="http://wpftoolkit.my-libraries.com/v5"
WindowStartupLocation="CenterOwner"
ResizeMode="NoResize"
Style="{DynamicResource WindowStyleX}"
ShowInTaskbar="False"
ShowActivated="True"
SizeToContent="Height"
Title="Add New Book"
Width="450">
..............
</Window>
XAML
<Style x:Key="WindowStyleX" TargetType="{x:Type Window}">
<Setter Property="WindowStyle" Value="None" />
<Setter Property="AllowsTransparency" Value="False" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderBrush="{DynamicResource BlackColor}" BorderThickness="1">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border
Grid.Row="0"
Grid.ColumnSpan="2"
Background="{DynamicResource BlackColor}">
<Grid>
<TextBlock
Grid.Column="1"
Margin="10,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="16"
Foreground="{DynamicResource WhiteTextForeground}"
Text="{TemplateBinding Title}" />
</Grid>
</Border>
<ContentPresenter Grid.Row="1" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
这不会消除关闭按钮,但它将阻止某人关闭窗口。
把这个放在文件后面的代码中:
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
e.Cancel = true;
}
我刚遇到类似的问题,乔怀特的解决方案似乎对我来说简单而干净。我重用了它,并将其定义为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>