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

后端 未结 2 1758
攒了一身酷
攒了一身酷 2021-01-19 00:24

Normally when you open a Modal Dialog and try to click on it\'s parent window the Modal Dialog\'s titlebar flashes. When creating a custom, borderless, chromeless, window in

相关标签:
2条回答
  • 2021-01-19 00:54
    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.

    0 讨论(0)
  • 2021-01-19 01:08

    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}"/>

    0 讨论(0)
提交回复
热议问题