WPF - 是否可以创建一个共享的基本窗口类,它既无边框又可调整大小?

时间:2016-10-25 08:53:45

标签: wpf

我可以按如下方式创建一个标准的WPF窗口,一切正常。

<Window x:Class="WpfWindowStyleTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        AllowsTransparency="True"
        Background="Transparent"
        ResizeMode="CanResizeWithGrip"
        SizeToContent="WidthAndHeight"
        TextOptions.TextFormattingMode="Display"
        TextOptions.TextRenderingMode="ClearType"
        Topmost="True"
        UseLayoutRounding="True"
        WindowStyle="None">
    <Grid>
        <Border Background="LightGreen"
                BorderBrush="Navy"
                BorderThickness="2"
                CornerRadius="4">

            // window content here ...

        </Border>
    </Grid>
</Window>

但是,我的应用程序需要所有窗口共享许多通用组件(超出简单边框的方式),因此我尝试将其提取到一个公共类中。

public class BaseView: Window
{
    static BaseView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseView), new FrameworkPropertyMetadata(typeof(BaseView)));
    }
}

在generic.xaml中使用以下样式

<Style BasedOn="{StaticResource {x:Type Window}}" TargetType="{x:Type local:BaseView}">
    <Setter Property="AllowsTransparency" Value="True" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="SizeToContent" Value="WidthAndHeight" />
    <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
    <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
    <Setter Property="Topmost" Value="True" />
    <Setter Property="UseLayoutRounding" Value="True" />
    <Setter Property="WindowStyle" Value="None" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:BaseView}">
                <Grid>
                    <AdornerDecorator>
                        <Border Background="LightGreen"
                                BorderBrush="Navy"
                                BorderThickness="2"
                                CornerRadius="4">

                            <ContentPresenter Margin="24" HorizontalAlignment="Left" />
                        </Border>
                    </AdornerDecorator>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这很好用。

但是,当我将另一个属性设置器添加到样式

<Setter Property="ResizeMode" Value="CanResizeWithGrip" />

忽略整个控件模板,只显示指定的窗口内容(在一个空的,可调整大小的窗口中)。

有什么方法吗?

1 个答案:

答案 0 :(得分:1)

您的问题取决于标准的Window风格;看一看:

<Style x:Key="{x:Type Window}" TargetType="{x:Type Window}">
    <Setter Property="Control.Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
    <Setter Property="Control.Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}">
                    <AdornerDecorator>
                        <ContentPresenter />
                    </AdornerDecorator>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Window.ResizeMode" Value="CanResizeWithGrip">
            <Setter Property="Control.Template" Value="{StaticResource ħ}" />
        </Trigger>
    </Style.Triggers>
</Style>

如您所见,如果ResizeMode设置为CanResizeWithGrip,则触发器会更改Window的模板。

一个简单的解决方案可能是在您的模板中添加ResizeGrip,并避免您的样式继承自默认样式。类似的东西:

<Style TargetType="{x:Type local:BaseView}">
    <Setter Property="AllowsTransparency" Value="True" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="SizeToContent" Value="WidthAndHeight" />
    <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
    <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
    <Setter Property="Topmost" Value="True" />
    <Setter Property="UseLayoutRounding" Value="True" />
    <Setter Property="WindowStyle" Value="None" />

    <Setter Property="ResizeMode" Value="CanResizeWithGrip" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:BaseView}">
                <Grid>
                    <AdornerDecorator>
                        <Border Background="LightGreen"
                            BorderBrush="Navy"
                            BorderThickness="2"
                            CornerRadius="4">

                            <ContentPresenter Margin="24" HorizontalAlignment="Left" />
                        </Border>
                    </AdornerDecorator>
                    <ResizeGrip Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsTabStop="False" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我希望它可以帮到你。