【问题标题】:Get Toolkit Style Window with WPF使用 WPF 获取工具包样式窗口
【发布时间】:2011-08-25 17:04:40
【问题描述】:

我正在使用 WPF 工具包和扩展的 WPF 工具包,并注意到当我通过以下方式显示消息框时:

MessageBox.Show("...");

我得到以下...

我想让我的主应用程序窗口也使用这种样式。有办法吗?

编辑:我试过 WindowStyle="ToolWindow" 但它不起作用。

编辑:针对下面的回答,请看下图:

另外,我希望它有一个最大化和最小化按钮,但与关闭按钮的样式相同。

谢谢!

【问题讨论】:

    标签: c# wpf wpftoolkit


    【解决方案1】:

    你的问题很模糊。您没有在任何地方说您想要 MessageBox 样式的哪一部分,但我想我知道您在问什么(相同的颜色和窗口镶边)。

    由于您使用的是 MessageBox 的扩展工具包版本,因此您有两个选择。

    首先,您可以切换 Xaml 中的每个 Window 实例并将其替换为 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。

    HTH。

    这是模板 -

    <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>
    

    【讨论】:

    • 感谢您的回复,但是我不能使用子窗口,因为我需要能够使用隐藏和其他功能。我只是想知道如何将这种样式应用于 Window 类。
    • 您必须修改 Window 的模板本身。您可以使用上面的代码示例作为起点,但就像我说的那样,您需要自己制作窗口无边框并连接所有正常的窗口 chrome 内容(关闭、最小化等...)。
    【解决方案2】:

    我想在这里添加一个免责声明,我出于好奇很快就把它放在一起,最重要的是。除了在其中放置一些控件并运行它之外,我还没有测试过这么多。它有效,但不应被视为完全完整。我也认为可能有更好的方法来做到这一点,但我认为这至少会给你一个好的起点。

    向您的项目添加一个新的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 中创建路径。

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      将此添加到 xaml 编辑器中的窗口标记

      WindowStyle="ToolWindow"

      【讨论】:

      • 我刚刚尝试过,它只是使它变得方形和透明(Windows 7),并使关闭按钮更小。它没有上图的样子。
      【解决方案4】:

      您可以使用WPF Shell Integration Library 完全控制窗口的镶边。下载包含一个示例。

      PS。一个常见的误解是,您可以通过将 WindowStyle 设置为 None 来提供自定义 chrome。虽然这确实删除了默认镶边,但它有几个缺点,包括您渲染的任何镶边都需要处理大小调整/移动,并且您的窗口将在用户的任务栏上最大化,这是不可接受的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 2011-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多