渲染模板表演

时间:2012-01-07 21:24:23

标签: wpf performance datatemplate

我创建了一个propertyGrid之类的。 我使用了一个使用viewmodel对象的Item控件。 VM对象具有要显示的属性及其相关的DataTemplates。 一切都很好。我的属性网格实际上就像VS属性网格

我的问题是,每次使用更改所选对象(导致属性网格中的更改)时,都需要花费很多时间(取决于所选对象属性的数量)。我发现性能不佳的原因是模板加载和渲染。 所以我认为我可以通过为每个对象创建真正的控件来解决这个问题,而不仅仅是使用模板。 (为每个属性创建按钮和文本框)这将解决加载时间,我希望..

1-有没有办法使用数据模板创建真正的控件(在代码中)? 2-有没有其他方法可以改善我的Property网格的性能?

propGrid的主要代码附于此帖子

谢谢,Leon

CODE:

<DataTemplate x:Key="gridItemsControl" >    
        <Grid  Visibility="{Binding Visibility}">
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition MinWidth="60"   MaxWidth="350" Width="{Binding Source={StaticResource firstCulWidth},Path=Width,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource widthToGridLenConverter}}"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" Grid.ColumnSpan="2"
                            Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter},ConverterParameter=Category}">
                <StackPanel Orientation="Horizontal" Background="#FFA9BFD4" Height="25">
                    <Expander Template="{StaticResource SimpleExpanderTemp}"  ExpandDirection="Left"  IsExpanded="{Binding IsExpanded, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="3,0,5,0"/>
                    <Label Content="{Binding Path=CategoryName,Converter={StaticResource propertyNameToDiplayNameConverter}}" FontSize="12" Foreground="White"  VerticalAlignment="Top" />
                </StackPanel>
            </Border>
            <Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" 
                                Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
                <Label Margin="5,0,0,0"  Content="{Binding Path=DisplayName,Converter={StaticResource propertyNameToDiplayNameConverter}}"/>
            </Border>
            <GridSplitter  Grid.Row="0"  Grid.Column="0"  Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}" HorizontalAlignment="Right" Width="4" Background="Transparent"/>
            <Border  Grid.Column="1" BorderBrush="#ff333333" BorderThickness="0.5" 
                                Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
                <ContentPresenter Grid.Column="1" Margin="10,1,10,1" HorizontalAlignment="Left" 
                                        ContentTemplate="{Binding  Path=InlineTemplate}" />
            </Border>
        </Grid>
    </DataTemplate>

更新:这是容器

 <ItemsControl Name="propsDataGrid"   ItemsSource="{Binding Properties}" ItemTemplate ="{StaticResource gridItemsControl}">
                        <ItemsControl.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Close all expanders" Click="MenuItem_Click" Visibility="{Binding IsAlphaBeticSort,Converter={StaticResource boolToVisConverter},ConverterParameter=VisForFalse}"></MenuItem>
                                <MenuItem Header="Expand all" Name="mnExpandeAll"  Click="mnExpandeAll_Click"  Visibility="{Binding IsAlphaBeticSort,Converter={StaticResource boolToVisConverter},ConverterParameter=VisForFalse}"></MenuItem>
                            </ContextMenu>
                        </ItemsControl.ContextMenu>
                            <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <!--<ItemsControl.ItemTemplate>
                        <DataTemplate >
                                <Grid  Visibility="{Binding Visibility}">
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MinWidth="60"   MaxWidth="350" Width="{Binding Source={StaticResource firstCulWidth},Path=Width,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource widthToGridLenConverter}}"/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" Grid.ColumnSpan="2"
                                        Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter},ConverterParameter=Category}">
                                        <StackPanel Orientation="Horizontal" Background="#FFA9BFD4" Height="25">
                                            <Expander Template="{StaticResource SimpleExpanderTemp}"  ExpandDirection="Left"  IsExpanded="{Binding IsExpanded, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="3,0,5,0"/>
                                            <Label Content="{Binding Path=CategoryName,Converter={StaticResource propertyNameToDiplayNameConverter}}" FontSize="12" Foreground="White"  VerticalAlignment="Top" />
                                    </StackPanel>
                                </Border>
                                <Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" 
                                          Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
                                    <Label Margin="5,0,0,0"  Content="{Binding Path=DisplayName,Converter={StaticResource propertyNameToDiplayNameConverter}}"/>
                                </Border>
                                <GridSplitter  Grid.Row="0"  Grid.Column="0"  Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}" HorizontalAlignment="Right" Width="4" Background="Transparent"/>
                                <Border  Grid.Column="1" BorderBrush="#ff333333" BorderThickness="0.5" 
                                          Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
                                    <ContentPresenter Grid.Column="1" Margin="10,1,10,1" HorizontalAlignment="Left" 
                                                  ContentTemplate="{Binding  Path=InlineTemplate}" />
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>-->
                </ItemsControl>

1 个答案:

答案 0 :(得分:0)

DataTemplates创建“真正的控件”手动执行任务都没有任何好处,这是使用模板自动完成的,您唯一需要担心的是虚拟化(以便控制不会创建不在视图中的属性)以及模板的连接方式,以便不会不必要地触发它们的创建。

(顺便说一句,你创建网格的方式,设置它的宽度,看起来可能是多余的,你可能只需要share the size。)

要使ItemsControl虚拟化您需要的项目:

  1. ItemsPanel设置为VirtualizingStackPanel
  2. 拥有一个控件模板,其ScrollViewer所在的ItemsPresenter周围包含VirtualizingStackPanel
  3. ScrollViewer.CanContentScroll设置为true以启用允许虚拟化的项目滚动。
  4. e.g。

    <ItemsControl ItemsSource="{Binding Items}"
                  ScrollViewer.CanContentScroll="True">
        <ItemsControl.Template>
            <ControlTemplate>
                <Border Name="Bd" Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"
                        Padding="1">
                    <ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <!-- ... -->
    </ItemsControl>
    

    如果这仍然太慢,您可以制作模板的整个ItemsControl部分,该模板应用每种类型,因为此网格的内容可能取决于项目的类型,因此,只有在项目类型发生变化时才能创建不同的网格,同时您也可以缓存生成的模板(我从未尝试过这样做)。