Окно стиля Get Toolkit с WPF - PullRequest
1 голос
/ 25 августа 2011

Я использую инструментарий WPF и расширенный инструментарий WPF и замечаю, что при отображении окна сообщения через:

MessageBox.Show("...");

Я получаю следующее ...

enter image description here

Я бы хотел, чтобы мое главное окно приложения также использовало этот стиль. Есть ли способ сделать это?

РЕДАКТИРОВАТЬ: я пробовал WindowStyle = "ToolWindow", и он не работает.

Изменить: В ответ на ответ ниже, пожалуйста, см. Рисунок ниже:

enter image description here

Кроме того, я бы хотел, чтобы кнопка максимизации и минимизации имела такой же стиль, что и кнопка закрытия.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 28 августа 2011

Ваш вопрос довольно расплывчатый. Вы нигде не говорите, какую часть стиля MessageBox вы хотите, но я думаю, что я знаю, что вы спрашиваете (те же цвета и хром окна).

Поскольку вы используете версию MessageBox для Extended Toolkit, у вас есть два варианта.

Во-первых, вы можете отключить каждый экземпляр Window, который есть в вашем Xaml, и заменить его на extToolkit:ChildWindow (extToolkit - это пространство имен в xmlns: extToolkit = "http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended").

Это быстрый вариант, но он оставляет вас в беде с несколькими вещами. Title для одного отсутствует в ChildWindow и вместо него используется Caption. Это может быть достаточно для вас, если вы не слишком много делаете с самими Windows.

Ваш второй вариант - сам шаблон Window, используя ту же информацию о стиле из шаблонов MessageBox или ChildWindow. Шаблон для расширенного инструментария ChildWindow находится в нижней части этого ответа, но потребуется некоторое изменение, чтобы привести его в соответствие со свойствами Window. Вам также придется скрыть Chrome Window и иметь форму без полей, поскольку Chrome реализован в шаблоне.

Это не лучшая ситуация, и расширенный инструментарий должен иметь собственную реализацию Window, если честно.

На вашем месте я бы попытался переключить Windows для запуска ChildWindows.

НТН.

Вот этот шаблон -

<ControlTemplate x:Key="ChildWindowControlTemplate1" TargetType="{x:Type extToolkit:ChildWindow}">
        <Grid x:Name="Root">
            <Grid.Resources>
                <Style x:Key="FocusVisualStyle" TargetType="{x:Type Control}">
                    <Setter Property="BorderBrush" Value="Black"/>
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="Margin" Value="-1"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Rectangle Fill="{TemplateBinding Background}" Margin="{TemplateBinding Margin}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5" StrokeDashArray="4 3">
                                    <Rectangle.RenderTransform>
                                        <TranslateTransform X="{Binding Left}" Y="{Binding Top}"/>
                                    </Rectangle.RenderTransform>
                                </Rectangle>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
                <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
            </Grid.Resources>
            <Grid x:Name="PART_WindowRoot" HorizontalAlignment="Left" Height="{TemplateBinding Height}" MinWidth="{TemplateBinding MinWidth}" MinHeight="{TemplateBinding MinHeight}" VerticalAlignment="Top" Width="{TemplateBinding Width}">
                <Grid.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Grid.RenderTransform>
                <Grid x:Name="WindowGrid">
                    <Border BorderBrush="{TemplateBinding WindowBorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5,5,0,0" Opacity="{TemplateBinding WindowOpacity}"/>
                    <Grid Background="{x:Null}" Margin="0">
                        <Border x:Name="WindowBorder" Background="{TemplateBinding WindowBackground}" CornerRadius="4,4,0,0" Margin="1" Opacity="{TemplateBinding WindowOpacity}"/>
                        <Border BorderBrush="White" BorderThickness="1" CornerRadius="4,4,0,0" Margin="1" Opacity="0.7"/>
                    </Grid>
                </Grid>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" MinHeight="26"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid x:Name="ContentGrid" Margin="6,0,6,6" Grid.Row="1">
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Border BorderBrush="White" BorderThickness="1" CornerRadius="1"/>
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0.1" Margin="1">
                            <ContentPresenter x:Name="Content" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/>
                        </Border>
                    </Grid>
                    <Border x:Name="PART_DragWidget" Background="Transparent" Grid.Column="1" CornerRadius="5,5,0,0" Margin="1,1,1,0">
                        <Grid>
                            <Grid x:Name="CaptionHeader" Margin="1,1,105,0" VerticalAlignment="Center">
                                <ContentControl x:Name="Caption" Content="{TemplateBinding Caption}" Foreground="{TemplateBinding CaptionForeground}" HorizontalAlignment="Stretch" IsTabStop="False" Margin="5,0,0,0"/>
                            </Grid>
                        </Grid>
                    </Border>
                </Grid>
                <Border BorderBrush="#A5FFFFFF" BorderThickness="1,0,1,1" CornerRadius="0,0,3,3" HorizontalAlignment="Right" Margin="0,1,7,0" VerticalAlignment="Top">
                    <Button x:Name="PART_CloseButton" Height="17" IsTabStop="False" Style="{TemplateBinding CloseButtonStyle}" Visibility="{TemplateBinding CloseButtonVisibility}" Width="43">
                        <Path Data="M0.5,0.5L4.5178828,0.5 6.0620003,3.125 7.4936447,0.5 11.5,0.5 11.5,1.5476431 8.7425003,6.1201854 11.5,10.359666 11.5,11.5 7.4941902,11.5 6.0620003,8.8740005 4.5172949,11.5 0.5,11.5 0.5,10.43379 3.3059995,6.1201582 0.5,1.4676378 0.5,0.5z" Fill="#E4FFFFFF" HorizontalAlignment="Center" Height="10" Stretch="Fill" Stroke="#FF535666" VerticalAlignment="Center" Width="12"/>
                    </Button>
                </Border>
            </Grid>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="WindowState" Value="Closed">
                <Setter Property="Visibility" Value="Collapsed"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
1 голос
/ 31 августа 2011

Вы можете использовать WPF Shell Integration Library , чтобы получить полный контроль над Chrome вашего окна.Загрузка включает в себя образец.

PS.Распространенным заблуждением является то, что вы можете предоставить пользовательский хром, установив для WindowStyle значение None.Несмотря на то, что это удаляет Chrome по умолчанию, у него есть несколько недостатков, в том числе то, что любой рендеринг Chrome должен будет обрабатывать изменение размера / перемещение, и что ваше окно будет максимизироваться по панели задач пользователя, что недопустимо.

1 голос
/ 30 августа 2011

Я хочу добавить здесь заявление об отказе от ответственности, которое я бросил вместе довольно быстро из любопытства, больше всего на свете. Я не так много тестировал, за исключением того, что уронил несколько элементов управления и запустил их. Это работает, но это не следует считать полностью завершенным. Я также думаю, что, возможно, есть лучшие способы сделать это, но я подумал, что это, по крайней мере, даст вам хорошую стартовую позицию.

Добавьте новый ResourceDictionary в свой проект и добавьте следующий XAML:

<ResourceDictionary
  x:Class="CustomWindow.BaseResource"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key="WindowStyle" TargetType="{x:Type Window}">
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="WindowStyle" Value="None" />
    <Setter Property="ResizeMode" Value="NoResize" />
    <Setter Property="Background" Value="White" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type Window}">
          <Border
            x:Name="WindowBorder"
            BorderBrush="Black"
            BorderThickness="1">
            <Border.Background>
              <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Offset="0" Color="White" />
                <GradientStop Offset="1" Color="#FFDADADA" />
              </LinearGradientBrush>
            </Border.Background>
            <Grid
              Width="{TemplateBinding Width}"
              Height="{TemplateBinding Height}"
              MinWidth="{TemplateBinding MinWidth}"
              MinHeight="{TemplateBinding MinHeight}"
              HorizontalAlignment="Left"
              VerticalAlignment="Top"
              Cursor="Arrow">
              <Grid.RowDefinitions>
                <RowDefinition Height="25" />
                <RowDefinition Height="*" />
              </Grid.RowDefinitions>
              <TextBlock
                Width="500"
                Height="23"
                Margin="11,2,0,0"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Text="{TemplateBinding Title}" />
              <Rectangle
                x:Name="TitleBar"
                Fill="Transparent"
                MouseDown="TitleBar_MouseDown" />
              <Rectangle
                Grid.RowSpan="2"
                Width="10"
                HorizontalAlignment="Left"
                Cursor="SizeWE"
                Fill="Transparent"
                MouseDown="Border_MouseDown"
                Tag="Left" />
              <Rectangle
                Grid.RowSpan="2"
                Width="10"
                HorizontalAlignment="Right"
                Cursor="SizeWE"
                Fill="Transparent"
                MouseDown="Border_MouseDown"
                Tag="Right" />
              <Rectangle
                Height="5"
                VerticalAlignment="Top"
                Cursor="SizeNS"
                Fill="Transparent"
                MouseDown="Border_MouseDown"
                Tag="Top" />
              <Rectangle
                Grid.Row="1"
                Height="10"
                VerticalAlignment="Bottom"
                Cursor="SizeNS"
                Fill="Transparent"
                MouseDown="Border_MouseDown"
                Tag="Bottom" />
              <StackPanel
                Margin="10,0"
                HorizontalAlignment="Right"
                VerticalAlignment="Top"
                Orientation="Horizontal">
                <Button
                  x:Name="MinimizeButton"
                  Width="43"
                  Height="17"
                  Click="MinimizeButton_Click"
                  IsTabStop="False">
                  min
                </Button>
                <Button
                  x:Name="MaximizeButton"
                  Width="43"
                  Height="17"
                  Margin="5,0"
                  Click="MaximizeButton_Click"
                  IsTabStop="False">
                  max
                </Button>
                <Button
                  x:Name="CloseButton"
                  Width="43"
                  Height="17"
                  Click="CloseButton_Click"
                  IsTabStop="False">
                  <Path
                    Width="12"
                    Height="10"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Data="M0.5,0.5L4.5178828,0.5 6.0620003,3.125 7.4936447,
                      0.5 11.5,0.5 11.5,1.5476431 8.7425003,6.1201854 11.5,
                      10.359666 11.5,11.5 7.4941902,11.5 6.0620003,8.8740005 
                      4.5172949,11.5 0.5,11.5 0.5,10.43379 3.3059995,
                      6.1201582 0.5,1.4676378 0.5,0.5z"
                    Fill="#E4FFFFFF"
                    Stretch="Fill"
                    Stroke="#FF535666" />
                </Button>
              </StackPanel>
              <Border
                Grid.Row="1"
                Margin="10,0,10,10"
                BorderBrush="Black"
                BorderThickness="1">
                <Grid>
                  <Rectangle Fill="White" />
                  <ContentPresenter Content="{TemplateBinding Content}" />
                </Grid>
              </Border>
            </Grid>
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Для наглядности предположим, что мы назвали ResourceDictionary, BaseResource.xaml .

Затем добавьте новый класс в тот же каталог, в который вы добавили ресурс, и назовите файл BaseResource.xaml.cs , подставив фактическое имя вашего файла XAML.

Вернитесь к BaseResource.xaml и измените свойство x:Class="CustomWindow.BaseResource" на полное имя типа ResourceDictionary. При правильном изменении Visual Studio должна пожаловаться на наличие дублирующего определения в BaseResource.xaml.cs. Исправьте это, добавив модификатор ключевого слова partial к классу в файле .cs.

Наконец, добавьте следующий код в файл кода:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

namespace CustomWindow
{
    public partial class BaseResource
    {
        private const uint WM_SYSCOMMAND = 0x112;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr 
            SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            Window.GetWindow((DependencyObject) sender).Close();
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            Window.GetWindow((DependencyObject) sender).WindowState = WindowState.Minimized;
        }

        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            var window = Window.GetWindow((DependencyObject) sender);
            window.WindowState = 
              (window.WindowState == WindowState.Maximized) ? WindowState.Normal : WindowState.Maximized;
        }

        private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            Window.GetWindow((DependencyObject) sender).DragMove();
        }

        private void Border_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            var direction = (Direction)Enum.Parse(typeof(Direction), ((FrameworkElement)sender).Tag.ToString());
            ResizeWindow(PresentationSource.FromVisual((Visual)sender) as HwndSource, direction);
        }

        private void ResizeWindow(HwndSource hwndSource, Direction direction)
        {
            SendMessage(hwndSource.Handle, WM_SYSCOMMAND, (int)(61440 + direction), 0);
        }

        private enum Direction
        {
            Left = 1,
            Right = 2,
            Top = 3,
            TopLeft = 4,
            TopRight = 5,
            Bottom = 6,
            BottomLeft = 7,
            BottomRight = 8,
        }
    }
}

Затем добавьте ResourceDictionary в глобальные ресурсы приложения. Снова замените BaseResource.xaml именем вашего файла, если оно отличается.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/BaseResource.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Добавить стиль к целевому окну.

<Window
  ...
  Style="{StaticResource WindowStyle}">

Несколько вещей ...

Дизайнер портит стиль, когда нет контента. Вероятно, это из-за того, где я разместил TemplateBinding для высоты и ширины, но он отлично выглядит во время выполнения, поэтому я не стал больше связываться с ним. Я также не реализовал ручку изменения размера углов, но добавить ее в шаблон достаточно просто.

Наконец, я не рисовал значки для кнопок «Свернуть» и «Свернуть». Я сосу на создание путей в Blend.

Надеюсь, это поможет.

1 голос
/ 25 августа 2011

добавьте это в свой тег окна в редакторе xaml

WindowStyle = "ToolWindow"

...