2014-11-26 7 views
3

Обычно, когда вы открываете Modal Dialog и пытаетесь щелкнуть по его родительскому окну, загорается строка заголовка Modal Dialog. При создании пользовательского, без полей, без хромированного окна в WPF вы теряете все эти функции и должны самостоятельно перестраивать его. Я выглядел высоко и низко, и для меня жизнь не может понять, как заставить мое Модальное окно мигать. Хотя он по-прежнему звучит ...WPF: Как создать пользовательскую модальную диалоги?

Я полагаю, что мне нужно будет следить за некоторыми событиями в WndProc, которые мне придется обрабатывать, но я не могу понять, какое событие или как это сделать Это. Я пробовал наблюдать за изменением окна и событием смены окна, а также событием WM_ACTIVATE безрезультатно. Я уверен, что я просто пропустил что-то простое, но я был бы признателен за любую помощь в этом. Благодаря!

+0

Это сообщение WM_NCACTIVATE. Утилита Spy ++ может рассказать вам об этом. –

+0

Я использовал spy ++, но из того, что я могу сказать, WM_NCACTIVATE отправляет то же точное сообщение, является ли это модальное окно, теряющее фокус или немодальное окно. Это не очень полезно. Он также просто говорит мне, что окно активируется, я не уверен, как сказать из этого, что мне нужно FLASH в строке заголовка, а не просто рисовать активную строку заголовка. Не могли бы Вы уточнить? –

+0

Дело в том, что он отправляет сообщение много раз. Таким образом, он вспыхивает. –

ответ

4
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 и поместить содержимое вашего MessageBox в нем

    <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 (по умолчанию = ложь)

  4. написать XAML код главного окна следующим образом:

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

Таким образом, когда MessageBoxUC открыт он будет блокировать MainContentsUC от того щелкнул. и когда вы нажимаете на заднюю область (где цвет установлен на # 4FFF), триггер запускает раскадровку, и она мигает.

Если у вас есть несколько окон, вы можете реализовать различные шаблоны управления и выбирать между ними с помощью селектора шаблонов. поэтому вместо <local:MainContentsUC/> вы будете иметь

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

+0

Я хочу, чтобы это было новое окно, а не просто элемент управления. @Hans Passant заставил меня заострить в правильном направлении. Спасибо за помощь, хотя! –