WPF:如何使自定义模式对话框闪烁

本文关键字:模式 对话框 闪烁 自定义 何使 WPF | 更新日期: 2023-09-27 18:32:03

通常,当您打开模态对话框并尝试单击其父窗口时,模态对话框的标题栏会闪烁。在 WPF 中创建自定义、无边框、无镶边窗口时,您将丢失所有这些功能,必须自己重新生成它。我看了高看低,一辈子都不知道如何让我的模态窗口闪烁。虽然它仍然发出哔哔声...

我想我将不得不在 WndProc 中监视我必须处理的一些事件,但我无法弄清楚哪个事件或如何做到这一点。我尝试观察窗口更改和窗口更改事件以及WM_ACTIVATE事件无济于事。我确定我只是错过了一些简单的东西,但我会感谢对此的任何帮助。谢谢!

WPF:如何使自定义模式对话框闪烁

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        var retVal = IntPtr.Zero;
        switch (msg)
        {
            case UnsafeNativeConstants.WM_NCACTIVATE:
                retVal = UnsafeNativeMethods.DefWindowProc(hwnd, UnsafeNativeConstants.WM_NCACTIVATE, new IntPtr(1), new IntPtr(-1));
                AssociatedObject.UpdateTitlebar((int)wParam == 1 ? true : false);
                handled = true;
                break;
        }
        return retVal;
    }

我在附加到我的窗口的自定义行为中挂接的 WndProc。它在我的窗口上调用一个内部方法,该方法将相应地更新标题栏的颜色。

感谢@Hans Passant为我指出了正确的方向。

如果您没有完全找到要查找的内容,则有一种解决方法涉及根本不使用模态窗口。

以下是您可以做到这一点的方法:

  1. 创建一个名为 MainContentUC 的用户控件,并将 MainWindow 的内容放入其中
  2. 创建另一个名为 MessageBoxUC 的用户控件,并将消息框的内容放入其中

    <UserControl x:Name="root" Visibility="{Binding ElementName=root, Path=IsOpen}">
        <Grid Background="#4FFF"/>
            <Border HorizontalAlignment="Center" VerticalAlignment="Center" 
                    x:Name="border" Background="White"/>
            <Grid.Triggers>
                <EventTrigger RoutedEvent="MouseDown">
                    <BeginStoryboard>
                        <Storyboard Duration="0:0:1">
                            <ColorAnimation 
                                 Storyboard.TargetName="border" 
                                 Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" 
                                 To="Black" Duration="0:0:.2" RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Grid.Triggers>
        </Grid>
    </UserControl>
    
  3. 在 MessageBoxUC 中添加一个名为 IsOpen 的布尔依赖项属性(默认=false)

  4. 编写主窗口的 XAML 代码,如下所示:

    <Window xmlns:local="clr-namespace:MyWpfApplication">
        <Grid>
            <local:MainContentsUC/>
            <local:MessageBoxUC/>
        </Grid>
    </Window>
    

这样,当 MessageBoxUC 打开时,它将阻止 MainContentUC 被单击。当您单击后部区域(颜色设置为 #4FFF)时,触发器将运行情节提要并闪烁。

如果您有多个窗口,则可以实现不同的控件模板,并使用模板选择器在它们之间进行选择。 因此,您将拥有<local:MainContentsUC/>而不是

<ContentPresenter ContentTemplateSelector="{StaticResource mySelector}"/>