WPF:如何制作自定义模式对话框闪烁?

问题描述 投票:0回答:2

通常,当您打开模态对话框并尝试单击其父窗口时,模态对话框的标题栏会闪烁。在 WPF 中创建自定义、无边框、无边框窗口时,您将失去所有功能,必须自行重建。我左顾右盼,终生不知道如何让我的模态窗口闪烁。虽然它仍然发出嘟嘟声...

我想我必须在 WndProc 中监视一些我必须处理的事件,但我不知道是哪个事件或如何处理。我尝试观察窗口更改和窗口更改事件以及 WM_ACTIVATE 事件,但无济于事。我确信我只是错过了一些简单的事情,但我将不胜感激对此的任何帮助。谢谢!

c# wpf window custom-controls wndproc
2个回答
5
投票
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 为我指明了正确的方向。


0
投票

如果您没有完全找到所需的内容,有一个解决方法,即根本不使用模式窗口。

具体操作方法如下:

  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 打开时,它将阻止单击 MainContentsUC。当您单击后面区域(颜色设置为#4FFF)时,触发器将运行故事板并闪烁。

如果您有多个窗口,您可以实现不同的控件模板并使用模板选择器在它们之间进行选择。所以你将拥有

而不是
<local:MainContentsUC/>

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

© www.soinside.com 2019 - 2024. All rights reserved.