WPF RibbonWindow не показывает Grip для изменения размера окна
У меня есть RibbonWindow, где мой WindowStyle установлен на None, так что я не могу понять, что случилось с Grip для изменения размера окна?! Даже если для моих элементов управления установлено значение Margin, равное 0, в нижней части они будут скрыты... Это странное поведение.
Но если я изменю нижнее поле элементов управления, все будет в порядке, но Захват в любом случае не будет виден, вероятно, потому что часть клиентской области скрыта...
Я должен сказать, что если есть окно WPF, это не происходит, это происходит только с RibbonWindow. И я использую RibbonWindow, потому что лента имеет другой вид в правильном окне.
Так что я могу сделать, чтобы решить проблему с 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 ответ
Это было интригующим для отладки. Оказывается, что у стиля для окна есть ошибка: если система определена, чтобы иметь 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
почти как в оригинальном стиле, только с одной модификацией: я прокомментировал установщик для WindowChrome.
MultiDataTrigger
это мое дополнение. Они проверяют ценность AllowsTransparency
свойство и применить право WindowChrome: оригинал, если значение false
и один с NonClientFrameEdges="None"
(вы также можете использовать GlassFrameThickness = 0
вместо) если значение true
,
ПРИМЕЧАНИЕ: это решение устраняет возможность изменения размера окна, используя края, изменение размера окна выполняется только ResizeGrip
,