WPF RibbonWindow не показывает Grip для изменения размера окна - PullRequest
3 голосов
/ 30 октября 2011

У меня есть RibbonWindow, где мой WindowStyle установлен на None, так что я не могу понять, что случилось с Grip, чтобы изменить размер окна ?! Даже если для моих элементов управления установлено значение Margin, равное 0, в нижней части они будут скрыты ... Это странное поведение.

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

Я должен сказать, что если есть окно WPF, этого не происходит, это происходит только с RibbonWindow. И я использую окно RibbonWindow, потому что лента выглядит по-другому в правильном окне.

Так что я могу сделать, чтобы решить проблему с ручкой?

Часть моего кода ...

<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 Ответ

7 голосов
/ 02 ноября 2011

Это было интригующе для отладки.Оказывается, что у стиля для окна есть ошибка: если система определена как 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 (я использую ресурсы приложения, определенные в App.xaml и определяющие только NonClientFrameEdges="None"):

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 почти такой же, как и в оригинальном стиле, только с одной модификацией: IЯ прокомментировал установщик для WindowChrome.

MultiDataTrigger s - мое дополнение.Они проверяют значение свойства AllowsTransparency и применяют правильный WindowChrome: оригинал, если значение false, и один с NonClientFrameEdges="None" (вы также можете использовать GlassFrameThickness = 0 вместо), если значение true.

ПРИМЕЧАНИЕ: это решение устраняет возможность изменения размера окна, используя края, изменение размера окна выполняется только с помощью ResizeGrip.

...