【问题标题】:WPF Collapsing VS RebindingWPF 折叠 VS 重新绑定
【发布时间】:2015-11-06 16:25:13
【问题描述】:

我有以下可以重构的代码:

<HierarchicalDataTemplate DataType    = "{x:Type data:FieldMapping}"
                          ItemsSource = "{Binding Path=FieldMappingItems}">
    <Grid Name="MainGrid"  >
        <Grid.ToolTip >
            <TextBlock Name="Tt" Text="{Binding Path=ToolTip}"/>
        </Grid.ToolTip>
        <Grid.ColumnDefinitions >
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock   Name="Error" Margin="0,0,5,0"  TextElement.FontWeight="Bold" TextElement.Foreground="Red"  Visibility="Collapsed" Text="!"/>
        <StackPanel Grid.Column="1" >
            <Image Source="../../icons\column.png" Name="Image"/>
            <Image Source="../../icons\Connect.png" Name="SourceImage" Visibility="Collapsed"/>
            <Image Source="../../icons\Service.png" Name="AttritubeImage" Visibility="Collapsed"/>
            <Image Source="../../icons\table.png" Name="SearchImage" Visibility="Collapsed"/>
            <Image Source="../../icons\surrogateKey.png" Name="TargetImage" Visibility="Collapsed"/>
            <Image Source="../../icons\Key16.png" Name="PrimayKeyImage" Visibility="Collapsed"/>
            <Image Source="../../icons\tempTable.png" Name="TempTableImage" Visibility="Collapsed"/>
            <Image Source="../../icons\Component16.png" Name="SPImage" Visibility="Collapsed"/>
            <Image Source="../../icons\DatabaseSelectCellSecure16.png" Name="RootImage" Visibility="Collapsed"/>
            <Image Source="../../icons\Console16.png" Name="ScriptImage" Visibility="Collapsed"/>
            <Image Source="../../icons\CodeWindowSelect16.png" Name="ProgramImage" Visibility="Collapsed"/>

        </StackPanel>
        <TextBlock Name="tb"  Margin="2,0,0,0"  Grid.Column="2" Text="{Binding Path=FieldName}"/>
        <TextBlock Name="tbSource" Margin="2,0,0,0"  Visibility="Collapsed"  Grid.Column="2" Text="{Binding Path=FullNodePath}"/>
    </Grid>
    <DataTemplate.Triggers>               
        <MultiDataTrigger >
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=Published}" Value="False"/>
                <Condition Binding="{Binding Path=FieldMappingType}" Value="TempTable"/>
            </MultiDataTrigger.Conditions>
            <Setter TargetName="tb" Property="FontStyle" Value="Italic"/>
        </MultiDataTrigger>
        <DataTrigger Binding="{Binding Path=Active}" Value="False">
            <Setter TargetName="MainGrid" Property="Opacity" Value="0.5"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=IsPrimaryKey}" Value="True">
            <Setter TargetName="tb" Property="Margin" Value="4,0,0,0"/>
            <Setter TargetName="Image" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="PrimayKeyImage" Property="Visibility" Value="Visible"/>
            <Setter TargetName="SourceImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="TargetImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="RootImage" Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=FieldMappingType}" Value="Table">
            <Setter TargetName="tb" Property="Margin" Value="4,0,0,0"/>
            <Setter TargetName="Image" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="SourceImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="PrimayKeyImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="TargetImage" Property="Visibility" Value="Visible"/>
            <Setter TargetName="RootImage" Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=FieldMappingType}" Value="TempTable">
            <Setter TargetName="tb" Property="Margin" Value="4,0,0,0"/>
            <Setter TargetName="Image" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="SourceImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="PrimayKeyImage" Property="Visibility" Value="Collapsed"/>
            <Setter TargetName="TempTableImage" Property="Visibility" Value="Visible"/>
            <Setter TargetName="RootImage" Property="Visibility" Value="Collapsed"/>
            <!--<Setter TargetName="tb" Property="Margin" Value="15,0,0,0"/>-->
        </DataTrigger>
</HierarchicalDataTemplate>

如您所见,有很多图像被折叠起来,然后根据对象的类型显示所需的图像。

我很欣赏这是一团糟,我已通过以下方式对其进行了重构:

<Grid Name="MainGrid">
                <Grid.ToolTip>
                    <TextBlock Name="Tt" Text="{Binding Path=ToolTip}" />
                </Grid.ToolTip>

                <StackPanel Orientation="Horizontal">
                    <TextBlock  x:Name="Error" Margin="0,0,5,0"  TextElement.FontWeight="Bold" TextElement.Foreground="Red"  Visibility="{Binding Path=Warning, Converter={StaticResource BooleanToVisibility}}" Text="!"/>
                    <Image x:Name="Icon" Source="../../icons\column.png" />
                    <TextBlock x:Name="tb" Margin="2,0,0,0" Text="{Binding Path=FieldName}" />
                </StackPanel>

            </Grid>
            <DataTemplate.Triggers>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Published}" Value="False" />
                        <Condition Binding="{Binding Path=FieldMappingType}" Value="TempTable" />
                    </MultiDataTrigger.Conditions>
                    <Setter TargetName="tb" Property="FontStyle" Value="Italic" />
                </MultiDataTrigger>

                <DataTrigger Binding="{Binding Path=Active}" Value="False">
                    <Setter TargetName="MainGrid" Property="Opacity" Value="0.5" />
                </DataTrigger>

                <DataTrigger Binding="{Binding Path=IsPrimaryKey}" Value="True">
                    <Setter TargetName="tb" Property="Margin" Value="4,0,0,0" />
                    <Setter TargetName="Icon" Property="Source" Value="../../Icons/Key16.png" />
                </DataTrigger>

                <DataTrigger Binding="{Binding Path=FieldMappingType}" Value="TempTable">
                    <Setter TargetName="tb" Property="Margin" Value="4,0,0,0" />
                    <Setter TargetName="Icon" Property="Source" Value="../../Icons/tempTable.png" />
                </DataTrigger>

虽然我的重构更容易消化和简洁,但我想知道是否通过更改单个图像的绑定而不是切换多个图像的可见性来获得更好的性能。

【问题讨论】:

    标签: wpf performance rendering


    【解决方案1】:

    折叠/显示总是比更改绑定更高效。如果应用程序真的在速度上挣扎,这是一个轻松的胜利。

    原因是当绑定改变时,WPF 必须在后台重新生成整个可视化树。这很慢。如果 WPF 折叠/显示部分可视化树,它会进行一些有效的优化以使此操作非常快速。

    具有讽刺意味的是,更改绑定直观地吸引了程序员,而 C# 通常更易于阅读且更优雅。

    更新

    此规则仅适用于您要破坏/创建巨大的视觉树的情况。如果您的应用程序明显变慢,则将其视为一种优化,否则应避免,因为它通常需要更多的编程工作。

    【讨论】:

    • 您是否有任何文档来支持这一点,因为这似乎非常违反直觉。
    • 没有文档,这是基于经验的。每次我们切换标签时,应用程序的初稿都会冻结 3 秒钟,这几乎无法使用。第二稿使用了隐藏/显示,而不是交换 ViewModel,它是即时的。
    • 在您描述的场景中,这似乎是一个合理的预期。我想知道这些对象是否会存储在内存中?如果您在选项卡开关上看到即时响应,我希望它们会如此。因为这些都是树视图中的节点,所以我可以有很多节点。我不想分配这么多内存,因为它们的状态不会经常改变。
    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2011-02-09
    • 2017-07-23
    • 2012-05-23
    相关资源
    最近更新 更多