【问题标题】:Restyling the WPF Extended Toolkit's ChildWindow重新设置 WPF 扩展工具包的 ChildWindow 的样式
【发布时间】:2017-06-30 16:50:07
【问题描述】:

我有一个模式对话框,我正在使用 WPF 扩展工具包的 ChildWindow 显示,但我不喜欢窗口的默认外观,因为它不正确支持系统颜色(它具有强制白色背景)并且不使用时不适应 Windows Classic Shell。 因此,我尝试为 ChildWindow 创建自己的样式,但这样做我破坏了控件的对话框行为 - 我将如何设置它的样式以恢复这种行为?

我的对话框风格如下。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:wpfToolkit="http://schemas.xceed.com/wpf/xaml/toolkit">
    <Style TargetType="wpfToolkit:ChildWindow">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="wpfToolkit:ChildWindow">
                    <!--<Window WindowState="{TemplateBinding WindowState}" Visibility="{TemplateBinding Visibility}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}">-->
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Border Grid.RowSpan="2"
                                BorderThickness="2"
                                BorderBrush="Gold"/>
                            <Rectangle>
                                <Rectangle.Fill>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <LinearGradientBrush.GradientStops>
                                            <GradientStop Color="Lime"/>
                                            <GradientStop Color="DarkGreen"/>
                                        </LinearGradientBrush.GradientStops>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <TextBlock Foreground="White" Text="{TemplateBinding Caption}"/>
                            <ContentPresenter Grid.Row="1"/>
                        </Grid>
                    <!--</Window>-->
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

我尝试将它嵌套在一个窗口中以恢复对话框行为,但我得到一个运行时异常“窗口必须是树的根。不能将窗口添加为 Visual 的子级。”。我的风格需要什么?

【问题讨论】:

    标签: c# wpf xaml modal-dialog wpf-extended-toolkit


    【解决方案1】:

    从默认样式开始并根据您的需要进行自定义:

    XAML:

    <Window x:Class="WpfApp27.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        xmlns:local="clr-namespace:WpfApp27"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    
    <Window.Resources>
        <LinearGradientBrush x:Key="LinearGradientBrushStyle1" StartPoint="0,0" EndPoint="1,1">
            <LinearGradientBrush.GradientStops>
                <GradientStop Color="Lime"/>
                <GradientStop Color="DarkGreen" Offset="0.5"/>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
    
        <Style x:Key="ChildWindowStyle1" TargetType="{x:Type xctk:ChildWindow}">
            <Setter Property="Background" Value="Navy"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="WindowBackground" Value="{StaticResource LinearGradientBrushStyle1}"/>
            <Setter Property="MinWidth" Value="120"/>
            <Setter Property="MinHeight" Value="45"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type xctk:ChildWindow}">
                        <Grid x:Name="PART_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}">
                                <xctk:WindowControl x:Name="PART_WindowControl" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CloseButtonVisibility="{TemplateBinding CloseButtonVisibility}" CaptionForeground="{TemplateBinding CaptionForeground}" ContentTemplate="{TemplateBinding ContentTemplate}" CaptionFontSize="{TemplateBinding CaptionFontSize}" Caption="{TemplateBinding Caption}" Content="{TemplateBinding Content}" CaptionShadowBrush="{TemplateBinding CaptionShadowBrush}" CloseButtonStyle="{TemplateBinding CloseButtonStyle}" CaptionIcon="{TemplateBinding CaptionIcon}" Height="{TemplateBinding Height}" IsActive="{TemplateBinding IsActive}" WindowStyle="{TemplateBinding WindowStyle}" WindowBackground="{TemplateBinding WindowBackground}" WindowOpacity="{TemplateBinding WindowOpacity}" WindowInactiveBackground="{TemplateBinding WindowInactiveBackground}" WindowBorderBrush="{TemplateBinding WindowBorderBrush}" Width="{TemplateBinding Width}" WindowBorderThickness="{TemplateBinding WindowBorderThickness}"/>
                            </Grid>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="WindowState" Value="Closed">
                                <Setter Property="Visibility" Value="Collapsed"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.BasedOn>
                <Style TargetType="{x:Type xctk:WindowControl}">
                    <Setter Property="CloseButtonStyle">
                        <Setter.Value>
                            <Style TargetType="{x:Type Button}">
                                <Setter Property="Background" Value="Blue"/>
                                <Setter Property="OverridesDefaultStyle" Value="True"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Button}">
                                            <Border x:Name="border" BorderThickness="0" Background="{TemplateBinding Background}" Padding="1">
                                                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                            </Border>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsActive, RelativeSource={RelativeSource TemplatedParent}}" Value="False">
                                        <Setter Property="Background" Value="#FFBCBCBC"/>
                                    </DataTrigger>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="SkyBlue"/>
                                    </Trigger>
                                    <Trigger Property="IsPressed" Value="True">
                                        <Setter Property="Background" Value="#FF993D3D"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="BorderThickness" Value="1"/>
                    <Setter Property="Background" Value="White"/>
                    <Setter Property="CaptionFontSize" Value="15"/>
                    <Setter Property="CaptionForeground" Value="white"/>
                    <Setter Property="CaptionShadowBrush" Value="Transparent"/>
                    <Setter Property="WindowBorderBrush" Value="Gold"/>
                    <Setter Property="WindowBackground" Value="#FF0078D7"/>
                    <Setter Property="WindowBorderThickness" Value="5"/>
                    <Setter Property="WindowInactiveBackground" Value="#FFEBEBEB"/>
                    <Setter Property="IsTabStop" Value="False"/>
                    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate/>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Style.BasedOn>
        </Style>
    </Window.Resources>
    
    <Grid>
        <xctk:WindowContainer Grid.Row="0">
            <xctk:ChildWindow Grid.Row="0" Width="200" Height="150" Caption="Child Window" IsModal="True" WindowState="Open" Style="{DynamicResource ChildWindowStyle1}">
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <TextBlock>My Child Window</TextBlock>
                    <Button Width="75" Height="25">CHILD</Button>
                </StackPanel>
            </xctk:ChildWindow>
        </xctk:WindowContainer>
    </Grid>
    

    【讨论】:

    • 啊,看来我丢失的那块是WindowControl;我也想整理一下那个关闭按钮的样式,所以我需要重新设置WindowControl 的样式才能做到这一点吗?此外,您使用的名称(例如“PART_WindowRoot”)是否重要,或者这只是 Expression Blend 生成的?
    • 关闭按钮的样式已包含在 XAML 中。毫不奇怪,它被称为CloseButtonStyle。所以你可以改变它。是的,PART_WindowRoot 很重要,由工具生成。通常,这些名称在相应的代码隐藏中引用。您可以通过检查源代码来确认。
    • 对不起,我还没有合适的机会使用它;这个周末我可以继续这项工作。当我之前查看您的答案时,我完全错过了“CloseButtonStyle”,因为我希望在样式标签中看到它为TargetType={x:Type xctk:CloseButton}
    • 好的,没问题,有任何问题都可以告诉我。我在任何地方都找不到类型 CloseButton,但如果你知道它在哪里(程序集/命名空间),请指出来。
    • 你说得对,没有CloseButton,我只是假设。我已经实现了您提供的更多样式,但由于其他与 Prism 相关的原因,我的项目目前处于无法测试的状态。我想知道为什么“ChildWindowStyle1”在其中直接定义了BasedOn 样式;我已经设法实现了我的“ChildWindowStyle1”,并将该 BasedOn 样式的属性分配定义为它自己的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多