【发布时间】:2015-05-26 06:29:56
【问题描述】:
我使用 Microsoft.Windows.Shell dll 创建了一个带有自定义镶边的 WPF 窗口。 这是代码:
<Style TargetType="Window" x:Key="ChromeLessWindowStyle">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
GlassFrameThickness="0"
ResizeBorderThickness="5"
CornerRadius="5"
CaptionHeight="30">
</shell:WindowChrome>
</Setter.Value>
</Setter>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Grid Background="#FF595959" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Height="30" Background="#FF393939">
<DockPanel LastChildFill="False" Margin="0,1,5,0">
<TextBlock DockPanel.Dock="Left" Style="{DynamicResource {x:Static coreKeys:TextBlockKeys.Default}}" FontWeight="Bold" Text="{TemplateBinding Title}" Margin="10,0,0,0" VerticalAlignment="Center"/>
<!--Buttons-->
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsCloseButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Close}}" shell:WindowChrome.IsHitTestVisibleInChrome="True"/>
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMaximizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Maximize}}" Visibility="{TemplateBinding WindowState,Converter={StaticResource WindowStateToVisibilityConverter},ConverterParameter=MaximizeButton }" shell:WindowChrome.IsHitTestVisibleInChrome="True" />
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMaximizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Restore}}" Visibility="{TemplateBinding WindowState,Converter={StaticResource WindowStateToVisibilityConverter}, ConverterParameter=RestoreButton }" shell:WindowChrome.IsHitTestVisibleInChrome="True" />
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMinimizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Minimize}}" shell:WindowChrome.IsHitTestVisibleInChrome="True"/>
</DockPanel>
</Border>
<ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这在正常情况下非常有效,直到我需要使用 C# 代码使用窗口时才发现问题。 我有一个消息服务:
- 创建一个模式窗口。
- 使用 WPF 用户控件填充其内容。
- 将窗口的数据上下文设置为适当的 ViewModel。
- 显示窗口
下面是代码:
var userControl = viewRegistry.GetViewByKey(viewKey_); // Get the UserControl.
var modalWindow = new ModalCustomMessageDialog
{
// Set the content of the window as the user control
DataContext = viewModel_,
// Set the data context of the window as the ViewModel
Owner = Util.AppMainWindow,
// Set the owner of the modal window to the app window.
WindowStartupLocation = WindowStartupLocation.CenterOwner,
//Title = viewModel.TitleText ?? "",
ShowInTaskbar = false,
Content = userControl,
SizeToContent = SizeToContent.WidthAndHeight
};
if (showAsToolWindow_)
{
modalWindow.ResizeMode = ResizeMode.NoResize;
modalWindow.WindowStyle = WindowStyle.ToolWindow;
}
modalWindow.Loaded += modalWindow_Loaded;
modalWindow.Closed += CleanModalWindow;
modalWindow.Show();
注意这一行
SizeToContent = SizeToContent.WidthAndHeight
这负责调整窗口大小以符合用户控件的宽度和高度。 这样生成的模态窗口在窗口的右侧和底部有一个粗黑的轮廓。像这样:
窗口应该是这样的(并且在调整大小之后):
有几点值得注意:
调整窗口大小后,此黑色轮廓消失。
如果 SizeToContent 设置为 SizeToContent.Height 或 SizeToContent.Width,则不会出现此轮廓。但随后它会分别吹掉模态窗口的宽度或高度。
-
我认为重绘窗口可能存在一些问题。所以我尝试了以下代码来重绘窗口:
private const int WmPaint = 0x000F; [DllImport("User32.dll")] public static extern Int64 SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); ...................... //Inside the Loaded event handler of the modalWindow var windowHandle = new WindowInteropHelper(modalWindow).Handle; SendMessage(windowHandle, WmPaint, IntPtr.Zero, IntPtr.Zero);这没有效果。
如果我为填充窗口的用户控件提供了固定的高度和宽度属性,则不会出现此问题。但是,我不能总是这样做。
消息服务已经存在很长时间了,这个幽灵轮廓最近在自定义 chrome 更改后出现了。
有人遇到过类似的情况吗?任何帮助将不胜感激。
【问题讨论】:
-
不要直接发送
WM_PAINT。使用InvalidateRect(hwnd, NULL, TRUE)使窗口的客户区无效,使用UpdateWindow(hwnd)强制立即重绘。我不认为这是解决您问题的方法,但这样说可以避免将来出现错误... -
您找到解决问题的方法了吗?我自己也遇到了完全相同的问题,并且已经在网上扫描了解决方案,但到目前为止还没有发现任何解决方案。