WPF RibbonWindow不显示Grip to resize窗口

时间:2011-10-30 15:10:41

标签: wpf xaml wpf-controls ribboncontrolslibrary

我有一个RibbonWindow,我的WindowStyle设置为None,所以我无法理解的是Grip发生了什么调整窗口的大小?!即使我的控件的底部部分的边距设置为0也会被隐藏......这是一种奇怪的行为。

但是如果我改变控件的底部边距就可以了,但无论如何都看不到Grip,可能是因为部分客户区被隐藏了......

我必须说,如果有一个WPF窗口,这不会发生,它只发生在RibbonWindow上。我正在使用RibbonWindow,因为Ribbon在适当的窗口中有其他外观。

那么我该如何解决Grip的问题?

我的一些代码......

<rib:RibbonWindow x:Class="MyApp.Views.MainView"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:rib="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
                  AllowsTransparency="True"
                  Background="Transparent"
                  Height="750"
                  ResizeMode="CanResizeWithGrip"
                  Width="1000"
                  WindowStartupLocation="CenterScreen"
                  WindowStyle="None">

    <Grid Margin="0, 0, 0, 20">
        <Border Background="Black"
                CornerRadius="5"
                Opacity="0.5"/>
    </Grid>
</rib:RibbonWindow>

提前致谢!

1 个答案:

答案 0 :(得分:7)

这对调试很有吸引力。事实证明,窗口的样式有一个错误:如果系统定义为IsGlassEnabled == true(在Win7 Aero主题中使其成为true),那么窗口依赖于Microsoft.Windows.Shell.WindowChrome (来自Microsoft.Windows.Shell程序集)绘制窗口的边框和顶部按钮;并且此WindowChrome将其GlassFrameThickness属性设置为8,30,8,8并将NonClientFrameEdges设置为Bottom

由于AllowsTransparency == true因为WindowChrome玻璃边框是透明的,但窗口仍然会从整个窗口大小“切割”其厚度,因为NonClientFrameEdges="Bottom"定义了ResizeGrip,因此切割了ResizeGrip来自视野。

如果您(疯狂地)将窗口拖到屏幕上,您可以看到这一点 - 您会看到WindowChrome闪烁。

要解决此问题,我们需要定义一个新的NonClientFrameEdges="None" GlassFrameThickness = 0(或IsGlassEnabled == true && AllowsTransparency == true或两者),并仅在NonClientFrameEdges="None"时将其分配给窗口(我是使用App.xaml中定义的应用程序资源并仅定义1. Add these namespaces to App.xaml: xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary" xmlns:ribbonPrimitives="clr-namespace:Microsoft.Windows.Controls.Ribbon.Primitives;assembly=RibbonControlsLibrary" xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell" 2. Add these resources: <ribbonPrimitives:RibbonWindowSmallIconConverter x:Key="RibbonWindowSmallIconConverter" /> <shell:WindowChrome x:Key="WindowChromeWithGlassAndTransparency" NonClientFrameEdges="None" /> <Style x:Key="MyStyle" TargetType="{x:Type ribbon:RibbonWindow}"> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Path=IsGlassEnabled, Source={x:Static shell:SystemParameters2.Current}}" Value="True" /> <Condition Binding="{Binding AllowsTransparency, RelativeSource={RelativeSource Mode=Self}}" Value="False" /> </MultiDataTrigger.Conditions> <Setter Property="shell:WindowChrome.WindowChrome" Value="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type ribbon:Ribbon}, ResourceId=WindowChromeAeroWithGlass}}" /> </MultiDataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Path=IsGlassEnabled, Source={x:Static shell:SystemParameters2.Current}}" Value="True" /> <Condition Binding="{Binding AllowsTransparency, RelativeSource={RelativeSource Mode=Self}}" Value="True" /> </MultiDataTrigger.Conditions> <Setter Property="shell:WindowChrome.WindowChrome" Value="{DynamicResource WindowChromeWithGlassAndTransparency}" /> </MultiDataTrigger> <DataTrigger Binding="{Binding Path=IsGlassEnabled, Source={x:Static shell:SystemParameters2.Current}}" Value="True"> <!--This is the original setter of the chrome that makes all the trouble--> <!--<Setter Property="shell:WindowChrome.WindowChrome" Value="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type ribbon:Ribbon}, ResourceId=WindowChromeAeroWithGlass}}" />--> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ribbon:RibbonWindow}"> <Grid> <Border Name="PART_ClientAreaBorder" Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Margin="{Binding Path=WindowNonClientFrameThickness, Source={x:Static shell:SystemParameters2.Current}}" /> <Border BorderThickness="{Binding Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness, RelativeSource={RelativeSource TemplatedParent}}"> <Grid> <Image Name="PART_Icon" shell:WindowChrome.IsHitTestVisibleInChrome="True" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon, Converter={StaticResource RibbonWindowSmallIconConverter }}" Width="{Binding Path=SmallIconSize.Width, Source={x:Static shell:SystemParameters2.Current}}" Height="{Binding Path=SmallIconSize.Height, Source={x:Static shell:SystemParameters2.Current}}" /> <AdornerDecorator> <ContentPresenter Name="PART_RootContentPresenter" /> </AdornerDecorator> <ResizeGrip Name="WindowResizeGrip" shell:WindowChrome.ResizeGripDirection="BottomRight" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="False" /> </Grid> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Value="{x:Null}" Property="Icon"> <Setter TargetName="PART_Icon" Property="Source" Value="/RibbonControlsLibrary;component/Images/GlassyDefaultSystemIcon.png" /> </Trigger> <Trigger Property="WindowState" Value="Maximized"> <Setter TargetName="PART_Icon" Property="Margin" Value="0,2,0,0" /> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ResizeMode" Value="CanResizeWithGrip" /> <Condition Property="WindowState" Value="Normal" /> </MultiTrigger.Conditions> <Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible" /> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </DataTrigger> </Style.Triggers> </Style> 3. In your window use the new style: <rib:RibbonWindow .... Style="{StaticResource MyStyle}"> .... </rib:RibbonWindow> ):

DataTrigger

MultiDataTrigger几乎和原始样式一样,只有一个修改:我已经评论了WindowChrome的setter。

AllowsTransparency是我的补充。他们检查false属性的值并应用正确的WindowChrome:如果值为NonClientFrameEdges="None",则为原始值;如果为GlassFrameThickness = 0,则应用true(如果值为ResizeGrip

注意:此解决方案无法使用边缘调整窗口大小,窗口的大小调整仅由{{1}}完成。