WPF: How do I make a custom modal dialog flash?

微笑、不失礼 提交于 2019-12-01 18:05:58
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;
    }

The WndProc I have hooked up in a custom behavior that's attached to my window. It calls an internal method on my window that will update the color of the Titlebar appropriately.

Thanks to @Hans Passant for pointing me in the right direction.

If you didn't exactly find what you're looking for, there is a workaround which involves not using a modal window at all.

Here's how you can do it:

  1. create a user control named MainContentUC and put the contents of MainWindow in it
  2. create another user control named MessageBoxUC and put the contents of your messagebox in it

    <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. add a boolean dependency property in MessageBoxUC named IsOpen (default=false)

  4. write xaml code of your main window as follows:

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

This way when the MessageBoxUC is open it will block MainContentsUC from being clicked. and when you click on the back area (where color is set to #4FFF) the trigger runs the storyboard and it blinks.

if you have several windows you can implement different control templates and choose between them using a template selector. so instead of <local:MainContentsUC/> you will have

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!