Я начал создавать приложение Wpf, повторно изменив хром в главном окне. Мой шаблон Chrome содержит 4 кнопки, каждая из которых имеет шаблон, который отображает границу с изображением внутри, и использует триггер и цветовую анимацию, чтобы перекрасить границу, чтобы обеспечить эффект наведения мыши. Остальная часть шаблона является статической, а содержимое окна представляет собой кнопку (просто для отображения чего-либо). У меня для AllowTransparency установлено значение True.
Проблема, с которой я столкнулся, заключается в том, что когда окно маленькое (скажем, 800 Вт x 500 ч), анимации работают нормально, они запускаются в момент входа мыши и играют с правильной скоростью, но когда я увеличиваю окно, анимации замедляются и при запуске отстает мышь, входящая в кнопку, до тех пор, пока окно не будет развернуто, и вам придется оставить мышь, сидящую над кнопкой, на некоторое время, прежде чем анимация будет воспроизводиться и когда она будет работать очень резко и медленно.
Я пытался отследить эту проблему, но безрезультатно:
- Удостоверился, что только анимации xaml не воспроизводились, vb или другие обработчики событий выполнялись одновременно.
- Определены значения высоты, ширины и ZIndex на содержащей StackPanel, надеюсь, ?? wpf будет перерисовывать только содержимое StackPanel.
- Удалено 3 из 4 кнопок.
- Пробовал на разных экранах (на которых используются разные видеокарты).
- Переконфигурировал мою систему, чтобы она использовала только один экран.
- Убедитесь, что аппаратное ускорение включено.
- Запустил Монитор ресурсов и заметил, что когда окно маленькое, то постоянно движется по кнопкам, использует около 2% ресурсов моего процессора, но когда окно развернуто, используется около 23%.
Я предполагаю, что wpf перерисовывает намного больше, чем я ожидаю, но я не знаю, как это остановить, если это так.
Любая помощь будет приветствоваться.
Извините за огромный список Xaml.
Окно:
<Window x:Class="Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="{Binding ShellState,
Mode=OneWayToSource}"
Title="{Binding Title,
Mode=OneTime}"
Style="{Binding ShellStyling,
Mode=OneTime}"
WindowStartupLocation="CenterScreen"><!-- ShellStyling = MainWindowShellStyle-->
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="{Binding TitleHeight,
Mode=OneTime}"
ResizeBorderThickness="{Binding ResizeBorderThickness,
Mode=OneTime}"
GlassFrameThickness="0"/>
</WindowChrome.WindowChrome>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Name="Stage"
Grid.Column="0"
Grid.Row="1"/>
</Grid>
</Window>
Стили:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key = "ChromeButtonBaseStyle"
TargetType = "{x:Type Button}">
<Setter Property = "Template"
Value = "{StaticResource MizedButtonTemplate}"/>
<Setter Property = "WindowChrome.IsHitTestVisibleInChrome"
Value = "True"/>
<Setter Property = "SnapsToDevicePixels"
Value = "True"/>
<Setter Property = "ToolTipService.Placement"
Value = "Bottom"/>
<Setter Property = "ToolTipService.ShowOnDisabled"
Value = "True"/>
<Setter Property = "VerticalAlignment"
Value = "Bottom"/>
<Setter Property = "HorizontalAlignment"
Value = "Center"/>
</Style>
<Style x:Key = "ChromeButtonImageBaseStyle"
TargetType = "Image">
<Setter Property = "SnapsToDevicePixels"
Value = "True"/>
<Setter Property = "ToolTipService.Placement"
Value = "Bottom"/>
<Setter Property = "Stretch"
Value = "None"/>
<Setter Property = "RenderOptions.BitmapScalingMode"
Value = "NearestNeighbor"/>
<Setter Property = "WindowChrome.IsHitTestVisibleInChrome"
Value = "True"/>
</Style>
<Style x:Key = "ChromeButtonImageStyle"
TargetType = "Image"
BasedOn = "{StaticResource ChromeButtonImageBaseStyle}">
<Setter Property = "Height"
Value = "{Binding ImageHeight,
Mode=OneTime}"/>
<Setter Property = "Width"
Value = "{Binding ImageWidth,
Mode=OneTime}"/>
</Style>
<Style x:Key = "ChromeButtonsContainerStyle"
TargetType = "Border">
<Setter Property = "Background"
Value = "{StaticResource BackgroundBrush}"/>
</Style>
<Style x:Key = "ChromeButtonsInnerContainerStyle"
TargetType = "{x:Type StackPanel}">
<Setter Property = "Orientation"
Value = "Horizontal"/>
<Setter Property = "VerticalAlignment"
Value = "Bottom"/>
</Style>
<Style TargetType = "{x:Type Button}"
x:Key = "ChromeButtonStyle"
BasedOn = "{StaticResource ChromeButtonBaseStyle}">
<Setter Property = "Border.CornerRadius"
Value = "{Binding CornerRadius,
Mode=OneTime}"/>
<Setter Property = "Padding"
Value = "{Binding ImagePadding,
Mode=OneTime}"/>
<Setter Property = "Margin"
Value = "{Binding ImageMargin,
Mode=OneTime}"/>
<Setter Property = "ToolTipService.VerticalOffset"
Value = "{Binding ToolTipVerticalOffset,
Mode=OneTime}"/>
<Setter Property = "ToolTipService.HorizontalOffset"
Value = "{Binding ToolTipHorizontalOffset,
Mode=OneTime}"/>
</Style>
<Style TargetType = "{x:Type Button}"
x:Key = "CloseButtonStyle"
BasedOn = "{StaticResource ChromeButtonStyle}">
<Setter Property = "Template"
Value = "{StaticResource CloseButtonTemplate}"/>
<Setter Property = "ToolTipService.ToolTip"
Value = "{Binding ToolTipText}"/>
<EventSetter Event = "Click"
Handler = "HandleCloseWindow" />
</Style>
<Style x:Key = "ContainerGridStyle"
TargetType = "Grid">
<Setter Property = "Background"
Value = "Transparent"/>
</Style>
<Style x:Key = "ContentContainerStyle"
TargetType = "Border">
<Setter Property = "Background"
Value = "{StaticResource BackgroundBrush}"/>
</Style>
<Style x:Key = "GripHandleStyle"
TargetType = "Image">
<Setter Property = "Width"
Value = "{Binding GripHandleWidth,
Mode=OneTime}"/>
<Setter Property = "Height"
Value = "{Binding TitleHeight,
Mode=OneTime}"/>
<Setter Property = "Stretch"
Value = "None"/>
<Setter Property = "SnapsToDevicePixels"
Value = "True"/>
<Setter Property = "Margin"
Value = "0"/>
<Setter Property = "HorizontalAlignment"
Value = "Right"/>
<Setter Property = "Source"
Value = "{Binding GripHandleDefinition,
Mode=OneTime}"/>
<Setter Property = "RenderOptions.BitmapScalingMode"
Value = "NearestNeighbor"/>
</Style>
<Style x:Key = "InnerBorderStyle"
TargetType = "{x:Type Border}">
<Setter Property = "Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth = "0"
BlurRadius = "8"
RenderingBias = "Quality"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key = "MaximizeButtonStyle"
TargetType = "Button"
BasedOn = "{StaticResource ChromeButtonStyle}">
<Setter Property = "ToolTipService.ToolTip"
Value = "{Binding ToolTipText}"/>
<EventSetter Event = "Click"
Handler = "HandleMaximizeWindow"/>
</Style>
<Style x:Key = "MinimizeButtonStyle"
TargetType = "Button"
BasedOn = "{StaticResource ChromeButtonStyle}">
<Setter Property = "ToolTipService.ToolTip"
Value = "{Binding ToolTipText}"/>
<EventSetter Event = "Click"
Handler = "HandleMinimizeWindow"/>
</Style>
<Style x:Key = "OuterBorderStyle"
TargetType = "{x:Type Border}">
<Setter Property = "BorderThickness"
Value = "0"/>
<Setter Property = "BorderBrush"
Value = "{x:Null}"/>
<Setter Property = "Background"
Value = "Transparent"/>
<Setter Property = "Padding"
Value = "{Binding RelativeSource = {RelativeSource TemplatedParent},
Path=DataContext.OuterMarginThickness,
Mode=OneWay}"/>
</Style>
<Style x:Key = "TitleLayoutStyle"
TargetType = "StackPanel">
<Setter Property = "Orientation"
Value = "Horizontal"/>
<Setter Property = "Height"
Value = "{Binding TitleHeight,
Mode=OneTime}"/>
</Style>
<Style x:Key = "TitleTextBaseStyle"
TargetType = "{x:Type TextBlock}">
<Setter Property = "FontFamily"
Value = "Segoe UI"/>
<Setter Property = "Foreground"
Value = "{StaticResource TitleBrush}"/>
<Setter Property = "VerticalAlignment"
Value = "Bottom"/>
<Setter Property = "Background"
Value = "Transparent"/>
<Setter Property = "Text"
Value = "{Binding Title,
Mode=OneTime}"/>
</Style>
<Style x:Key = "TitleTextStyle"
TargetType = "TextBlock"
BasedOn = "{StaticResource TitleTextBaseStyle}">
<Setter Property = "FontSize"
Value = "{Binding TitleTextFontSize,
Mode=OneTime}"/>
<Setter Property = "Margin"
Value = "{Binding TitleTextMargin,
Mode=OneTime}"/>
</Style>
<Style x:Key = "WindowShellBaseStyle"
TargetType = "{x:Type Window}">
<Setter Property = "OverridesDefaultStyle"
Value = "True"/>
<Setter Property = "WindowStyle"
Value = "None"/>
<Setter Property = "AllowsTransparency"
Value = "True"/>
</Style>
<Style x:Key = "MainWindowShellStyle"
TargetType = "{x:Type Window}"
BasedOn = "{StaticResource WindowShellBaseStyle}">
<Setter Property = "Height"
Value = "{Binding Height}"/>
<Setter Property = "Width"
Value = "{Binding Width}"/>
<Setter Property = "MaxHeight"
Value = "{Binding MaxHeight}"/>
<Setter Property = "MaxWidth"
Value = "{Binding MaxWidth}"/>
<Setter Property = "MinHeight"
Value = "{Binding MinHeight}"/>
<Setter Property = "MinWidth"
Value = "{Binding MinWidth}"/>
<Setter Property = "ShowInTaskbar"
Value = "{Binding ShowInTaskBar}"/>
</Style>
</ResourceDictionary>
Шаблоны:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source = "pack://application:,,,/WindowChromeColors.xaml"/>
<ResourceDictionary
Source = "pack://application:,,,/WindowChromeAnimations.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ControlTemplate TargetType = "{x:Type Button}"
x:Key = "CloseButtonTemplate">
<Border Padding = "{TemplateBinding Padding}"
Margin = "{TemplateBinding Margin}"
BorderThickness = "{TemplateBinding BorderThickness}"
CornerRadius = "{TemplateBinding Border.CornerRadius}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
SnapsToDevicePixels = "True">
<Border.BorderBrush>
<SolidColorBrush x:Name = "HoverBorderColor"
Color = "{StaticResource MouseOutBorder}"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush x:Name = "ButtonBackground"
Color = "{StaticResource Background}"/>
</Border.Background>
<Image Source="{Binding ImageSource}"
Style="{Binding ImageStyle}" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent = "MouseEnter">
<BeginStoryboard>
<Storyboard TargetName = "HoverBorderColor">
<!-- ReSharper disable once Xaml.InvalidResourceType -->
<StaticResource ResourceKey = "HoverBorderAnimation"/>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetName = "ButtonBackground">
<!-- ReSharper disable once Xaml.InvalidResourceType -->
<StaticResource ResourceKey = "CloseButtonHoverBgAnimation"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent = "MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName = "HoverBorderColor">
<!-- ReSharper disable once Xaml.InvalidResourceType -->
<StaticResource ResourceKey = "LeaveBorderAnimation"/>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetName = "ButtonBackground">
<!-- ReSharper disable once Xaml.InvalidResourceType -->
<StaticResource ResourceKey = "CloseButtonLeaveBgAnimation"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate TargetType="{x:Type Button}"
x:Key="MizedButtonTemplate">
<Border Padding="{TemplateBinding Padding}"
Margin="{TemplateBinding Margin}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding Border.CornerRadius}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
SnapsToDevicePixels="True"
Background="{StaticResource BackgroundBrush}"
>
<Border.BorderBrush>
<SolidColorBrush x:Name="HoverBorderColor"
Color="{StaticResource MouseOutBorder}" />
</Border.BorderBrush>
<Image Source="{Binding ImageSource}"
Style="{Binding ImageStyle}"/>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard TargetName="HoverBorderColor">
<!--ReSharper disable once Xaml.InvalidResourceType-->
<StaticResource ResourceKey="HoverBorderAnimation" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard TargetName="HoverBorderColor">
<!--ReSharper disable once Xaml.InvalidResourceType-->
<StaticResource ResourceKey="LeaveBorderAnimation" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="WindowShellTemplate"
TargetType="{x:Type Window}">
<Border Style="{StaticResource OuterBorderStyle}">
<Border Style="{StaticResource InnerBorderStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Column="0"
Grid.Row="0"
Style="{StaticResource ContainerGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Column="0"
Grid.Row="0"
Style="{StaticResource GripHandleStyle}"/>
<Border Grid.Column="2"
Grid.Row="0"
Style="{StaticResource ChromeButtonsContainerStyle}">
<StackPanel Style="{StaticResource ChromeButtonsInnerContainerStyle}">
<TextBlock Grid.Column="1"
Grid.Row="0"
Style="{StaticResource TitleTextStyle}" />
<Button DataContext="{Binding MinimizeButtonViewModel,
Mode=OneTime}"
Style="{StaticResource MinimizeButtonStyle}"
Visibility="{Binding Visibility,
Mode=OneTime}"
Tag = "{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Mode=OneTime}" />
<Button DataContext="{Binding MaximizeButtonViewModel,
Mode=OneTime}"
Style="{StaticResource MaximizeButtonStyle}"
Visibility="{Binding Visibility,
Mode=OneTime}"
Tag = "{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Mode=OneTime}" />
<Button DataContext="{Binding CloseButtonViewModel,
Mode=OneTime}"
Style="{StaticResource CloseButtonStyle}"
Visibility="{Binding Visibility,
Mode=OneTime}"
Tag="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Mode=OneWay}"
Command = "{Binding ClickAction,
Mode=OneTime}"
CommandParameter = "{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}},
Mode=OneTime}" />
</StackPanel>
</Border>
</Grid>
<Border Grid.Column="0"
Grid.Row="1"
Style="{StaticResource ContentContainerStyle}">
<ContentPresenter />
</Border>
</Grid>
</Border>
</Border>
</ControlTemplate>
</ResourceDictionary>
Анимации Все цветовые анимации такие же, как на рисунке ниже, они просто анимируют разные цвета.
<ColorAnimation x:Key="HoverBorderAnimation"
Storyboard.TargetProperty="Color"
To="{StaticResource MouseHoverBorder}"
Duration="0:0:0.25"
AutoReverse="False" />