Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 渲染模板性能_Wpf_Performance_Datatemplate - Fatal编程技术网

Wpf 渲染模板性能

Wpf 渲染模板性能,wpf,performance,datatemplate,Wpf,Performance,Datatemplate,我创建了一个类似propertyGrid的。 我使用了一个使用viewmodel对象的项控件。 VM对象具有要显示的属性及其相关的DataTemplates。 一切都很好。我的属性网格实际上与VS属性网格类似 我的问题是,每次使用更改选定对象(这会导致属性网格中的更改)都需要花费大量时间(取决于选定对象属性的数量)。我发现性能不好的原因是模板加载和渲染。 所以我想我可以通过为每个对象创建真正的控件来解决这个问题,而不仅仅是使用模板。(为每个属性创建按钮和文本框)我希望这将解决加载时间问题 1-是

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

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

1-是否有任何方法可以使用数据模板创建真正的控件(在代码中)? 2-是否有其他方法来提高我的物业网格的性能

propGrid的主要代码附在本文之后

谢谢你,里昂

代码:


更新:这是容器

 <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>

数据模板
创建“真正的控件”手动操作(使用模板自动完成)没有任何好处,您唯一需要担心的是虚拟化(以便不创建视图中属性的控件)以及模板的连接方式,以避免不必要地触发它们的创建

(顺便说一句,您创建栅格的方式,设置栅格宽度,看起来可能是多余的,您可能只需要这样做。)

要创建
ItemsControl
虚拟化所需的项目,请执行以下操作:

  • ItemsPanel
    设置为
  • ItemsPresenter
    周围有一个控件模板,其中包含一个
    ScrollViewer
    ,其中将显示
    VirtualizangStackPanel
  • ScrollViewer.CanContentScroll
    设置为
    true
    ,以启用按项滚动,从而允许虚拟化
  • e、 g

    
    

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

    包含/生成项目的控件是如何定义的?感谢H.B的重播,我想这样做的原因是避免创建那些控件(由临时创建的)不止一个。每次用户选择查看某个对象的属性时,我的属性网格都会加载/使用数据模板,因此我想通过为我的每个数据对象一次装入UIElements来改进这一点。@Leonoah:您可能绑定了一些错误的内容,而且您似乎错过了虚拟化的部分,仍然没有执行任何操作请不要提供容器的定义,这可以解释为什么您可能没有任何虚拟化。再次感谢H.B,我更新了帖子并添加了conatiner代码。@leonnoah:如果您定义了一个ItemsControl这样的控件,所有的项都将一次创建,我添加了一个关于虚拟化的示例,但这当然只有在您的网格足够多的项,其中一些项将被删除(如果在应用示例时,ItemsControl周围有一个scrollviewer,则应删除该项)。谢谢你,agian H.B!。我已经实现了VirtualzingStackPanel,但当我想显示其他对象的属性时,加载会持续大约1秒钟。我确信模板存在一些问题。我最大的问题是,对于我想显示的每个对象,其属性都有不同类型的数据,因此每次s使用不同的模板。控件的datacontext是某个Viewmodel的集合,该集合封装了模型(属性数据)及其相关的DataTemple。通过这种方式,我实现了PropertyGrid控件。我的concept错了吗?
     <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>
    
    <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>