用户控件的可视状态会降低渲染速度

时间:2016-12-13 14:40:02

标签: c# performance xaml uwp win-universal-app

我正在开发一个UWP应用程序,它有一个可以在GridView中呈现产品数量的视图,我为每个要渲染的产品创建了一个数据模板,下面是附加的XAML代码。

当我运行Visual Studio Profiler来调试渲染布局所花费的时间时,我发现在Layout部分下,每个Product模板的ListViewItemPresenter需要大约6-7 ms来渲染,所以如果我在GridView中有10个产品它增加了70毫秒的渲染,最终使UI变慢,我在视图中有加载器,在显示UI时显示,但我希望这个时间减少。

任何人都可以帮忙吗?

任何帮助都将受到高度赞赏。 提前谢谢。

<UserControl.Resources>
    <converters:ProductQuantityVisibilityConverter x:Key="ProductQuantityVisibilityConverter" />
    <!--<converters:DoubleDigitVisibilityConverter x:Key="DoubleDigitVisibilityConverter" />
    <converters:TripleDigitVisibilityConveter x:Key="TripleDigitVisibilityConveter" />
    <converters:FourDigitVisibilityConverter x:Key="FourDigitVisibilityConverter" />-->

    <Style TargetType="Button"
           BasedOn="{StaticResource ButtonWithNoBorder}"
           x:Name="QuantityButtonStyle">
        <Setter Property="Background"
                Value="White" />
        <Setter Property="HorizontalAlignment"
                Value="Stretch" />
        <Setter Property="HorizontalContentAlignment"
                Value="Left" />
        <Setter Property="Padding"
                Value="2,0" />
        <Setter Property="Foreground"
                Value="{StaticResource CancelButtonForeGround}" />
        <Setter Property="FontFamily"
                Value="Segoe UI Light" />
        <Setter Property="FontWeight"
                Value="Light" />
        <Setter Property="VerticalAlignment"
                Value="Stretch" />
        <Setter Property="VerticalContentAlignment"
                Value="Center" />
    </Style>

</UserControl.Resources>


<Grid Background="White">
    <VisualStateManager.VisualStateGroups>

        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <trigger:EqualsStateTrigger Value="{x:Bind ProductDetails.FontSizeSelector, Mode=OneWay}"
                                                EqualTo="1" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="txtQuantity.FontSize"
                            Value="57" />
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <trigger:EqualsStateTrigger Value="{x:Bind ProductDetails.FontSizeSelector, Mode=OneWay}"
                                                EqualTo="2" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="txtQuantity.FontSize"
                            Value="47" />
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <trigger:EqualsStateTrigger Value="{x:Bind ProductDetails.FontSizeSelector, Mode=OneWay}"
                                                EqualTo="3" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="txtQuantity.FontSize"
                            Value="33" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid>

        <!--#region When Quantity is zero-->
        <Grid x:Name="productWithZeroQuantity" 
              Padding="0">
            <Button x:Name="btnProductImage"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    Padding="0"
                    Style="{StaticResource ButtonWithNoBorder}"
                    Command="{x:Bind IncreaseQuantityCommand,Mode=OneWay}"
                    CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}"
                    Height="60"
                    Width="120">
                <Button.Background>
                    <ImageBrush Stretch="Fill"
                                ImageSource="{x:Bind ProductDetails.ImageSource, Mode=OneWay}" />
                </Button.Background>
                <Rectangle Width="{Binding ActualWidth, ElementName=btnProductImage}"
                           Height="{Binding ActualHeight, ElementName=btnProductImage}"
                           Margin="0">
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,0"
                                             EndPoint="0,1">
                            <GradientStop Offset="0.728"
                                          Color="#50FFFFFF" />
                            <GradientStop Offset="1"
                                          Color="#FFF9F1F1" />
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <i:Interaction.Behaviors>
                    <ic:EventTriggerBehavior EventName="Holding">
                        <ic:InvokeCommandAction Command="{x:Bind SetQuantityCommand, Mode=OneWay}"
                                                CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}" />
                    </ic:EventTriggerBehavior>
                    <ic:EventTriggerBehavior EventName="RightTapped">
                        <ic:InvokeCommandAction Command="{x:Bind SetQuantityCommand, Mode=OneWay}"
                                                CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}" />
                    </ic:EventTriggerBehavior>
                </i:Interaction.Behaviors>
            </Button>
        </Grid>
        <!--#endregion-->

        <!--#region When quantity is positive-->

        <Grid Padding="0"
              x:Name="ProductWithPositiveQuantity"
              Visibility="{Binding Quantity, Converter={StaticResource ProductQuantityVisibilityConverter}}"
              Grid.Row="1"
              Height="60"
              Width="120">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="2*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <Button x:Name="txtQuantity"
                    Style="{StaticResource QuantityButtonStyle}"
                    Command="{x:Bind IncreaseQuantityCommand,Mode=OneWay}"
                    FontSize="57"
                    Content="{x:Bind ProductDetails.Quantity, Mode=OneWay}"
                    CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}">
            </Button>
            <Button Background="{StaticResource LightGray}"
                    Grid.Column="1"
                    Opacity="0.95"
                    VerticalAlignment="Stretch"
                    HorizontalAlignment="Stretch"
                    HorizontalContentAlignment="Center"
                    VerticalContentAlignment="Center"
                    Style="{StaticResource ButtonWithNoBorder}"
                    Command="{x:Bind DecreaseQuantityCommand, Mode=OneWay}"
                    CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}">
                <Image Stretch="None"
                       Source="ms-appx:///Images/HotCategories/MinusIcon.png" />
            </Button>
            <i:Interaction.Behaviors>
                <ic:EventTriggerBehavior EventName="Holding">
                    <ic:InvokeCommandAction Command="{x:Bind SetQuantityCommand, Mode=OneWay}"
                                            CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}" />
                </ic:EventTriggerBehavior>
                <ic:EventTriggerBehavior EventName="RightTapped">
                    <ic:InvokeCommandAction Command="{x:Bind SetQuantityCommand, Mode=OneWay}"
                                            CommandParameter="{x:Bind ProductDetails.StockCode, Mode=OneWay}" />
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </Grid>

        <!--#endregion-->

    </Grid>
    <Border Background="{StaticResource DarkGray}"
            Height="20"
            Width="120"
            Grid.Row="1">
        <TextBlock Text="{x:Bind ProductDetails.Description, Mode=OneWay}"
                   Padding="3,2,2,2"
                   FontSize="12"
                   FontWeight="SemiBold"
                   TextTrimming="CharacterEllipsis"
                   HorizontalAlignment="Left"
                   Foreground="White" />
    </Border>
</Grid>

1 个答案:

答案 0 :(得分:0)

我发现每次更新时我们都完全更新了ObservableCollection,最终使渲染时间倍增导致闪烁。

我更新了代码,只更新了在集合中更改了值的列表项,这样它们就会再次渲染,导致每次重新渲染的UI都减少,从而消除了闪烁。