Анимации замедляются по мере увеличения размера окна - PullRequest
0 голосов
/ 06 ноября 2018

Я начал создавать приложение 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" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...