Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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_Pixelsense - Fatal编程技术网

Wpf 如何优化曲面列表框项目的样式?

Wpf 如何优化曲面列表框项目的样式?,wpf,pixelsense,Wpf,Pixelsense,我在一个SurfaceListBox中只有15个项目的性能方面遇到了问题 列表框是通过与我的viewmodel的源绑定创建的,我使用ItemContainerStyleSelector来选择要使用的三种样式之一。 然而,我仍然有8个ControlTemplates,因为我有4个dataitem可以显示的状态,加上选中该项时的4个状态 样式选择器非常简单: public class TaskStyleSelector : StyleSelector { public Style Defau

我在一个SurfaceListBox中只有15个项目的性能方面遇到了问题

列表框是通过与我的viewmodel的源绑定创建的,我使用ItemContainerStyleSelector来选择要使用的三种样式之一。 然而,我仍然有8个ControlTemplates,因为我有4个dataitem可以显示的状态,加上选中该项时的4个状态

样式选择器非常简单:

public class TaskStyleSelector : StyleSelector
{
    public Style DefaultStyle { get; set; }
    public Style OverdueStyle { get; set; }
    public Style PresentStyle { get; set; }
    public Style CompletedStyle { get; set; }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        var t = item as Sekoia.Karuna.Public.Models.Tasks.Task;
        if (t == null)
            return base.SelectStyle(item, container);

        if (t.Completed)
            return CompletedStyle;
        else if (t.IntervalStartTime <= DateTime.Now && t.IntervalEndTime >= DateTime.Now)
            return PresentStyle;
        else if (t.IntervalEndTime < DateTime.Now)
            return OverdueStyle;
        return DefaultStyle;
    }
}
公共类TaskStyleSelector:StyleSelector
{
公共样式DefaultStyle{get;set;}
公共样式OverdueStyle{get;set;}
公共样式PresentStyle{get;set;}
公共样式CompletedStyle{get;set;}
公共替代样式SelectStyle(对象项,DependencyObject容器)
{
var t=项目为Sekoia.Karuna.Public.Models.Tasks.Task;
如果(t==null)
返回基。选择样式(项目、容器);
如果(t.已完成)
返回CompletedStyle;
else if(t.IntervalStartTime=DateTime.Now)
回归当下风格;
else if(t.IntervalEndTime
我的控件模板如下所示:

    <ControlTemplate x:Key="defaultTaskTemplate">
            <Border BorderThickness="0, 0, 0, 1" Height="56" BorderBrush="{StaticResource SideBarShadowBrush}" Background="Transparent">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="56"/>
                        <ColumnDefinition Width="130"/>
                        <ColumnDefinition Width="214"/>
                        <ColumnDefinition Width="56"/>
                        <ColumnDefinition Width="56"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Padding="13,16,0,0" Grid.Column="1" Foreground="{StaticResource TextGreyBrush}"><Run Text="{Binding IntervalStartTime, StringFormat=\{0:hh:mm\}}"/><Run Text=" - "/><Run Text="{Binding IntervalEndTime, StringFormat=\{0:hh:mm\}}"/></TextBlock>
                    <TextBlock Padding="13,16,0,0" Grid.Column="2" Foreground="{StaticResource TextGreyBrush}" Text="{Binding Title}"/>
                    <Views:ArrowControl HorizontalAlignment="Center" Width="20" Grid.Column="4" Height="13" VerticalAlignment="Center" ArrowBrushColor="{StaticResource TextGrey}"/>
                    <Views:CheckMarkControl Width="30" Height="30" />
                </Grid>
            </Border>
        </ControlTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="normalTaskItemStyle" BasedOn="{StaticResource baseTaskStyle}">
            <Setter Property="Template" Value="{StaticResource defaultTaskTemplate}"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Template" Value="{StaticResource defaultSelectedTaskTemplate}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

对我来说,这看起来很简单。 但是我的风格是这样的:

    <ControlTemplate x:Key="defaultTaskTemplate">
            <Border BorderThickness="0, 0, 0, 1" Height="56" BorderBrush="{StaticResource SideBarShadowBrush}" Background="Transparent">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="56"/>
                        <ColumnDefinition Width="130"/>
                        <ColumnDefinition Width="214"/>
                        <ColumnDefinition Width="56"/>
                        <ColumnDefinition Width="56"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Padding="13,16,0,0" Grid.Column="1" Foreground="{StaticResource TextGreyBrush}"><Run Text="{Binding IntervalStartTime, StringFormat=\{0:hh:mm\}}"/><Run Text=" - "/><Run Text="{Binding IntervalEndTime, StringFormat=\{0:hh:mm\}}"/></TextBlock>
                    <TextBlock Padding="13,16,0,0" Grid.Column="2" Foreground="{StaticResource TextGreyBrush}" Text="{Binding Title}"/>
                    <Views:ArrowControl HorizontalAlignment="Center" Width="20" Grid.Column="4" Height="13" VerticalAlignment="Center" ArrowBrushColor="{StaticResource TextGrey}"/>
                    <Views:CheckMarkControl Width="30" Height="30" />
                </Grid>
            </Border>
        </ControlTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="normalTaskItemStyle" BasedOn="{StaticResource baseTaskStyle}">
            <Setter Property="Template" Value="{StaticResource defaultTaskTemplate}"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Template" Value="{StaticResource defaultSelectedTaskTemplate}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

如您所见,当选择更改时,我正在更改模板

我面临的是,当实际绑定到源代码时,窗口将挂起,等待列表框呈现这些项。当窗口打开时,我会显示一个“微调器”元素,表示我正在下载内容。下载完成后,我进行了数据绑定,看到微调器在被移除之前停止。微调器停止向我指示窗口线程挂起,因为绑定正在进行中。一旦初始绑定结束,我就可以滚动/平移了,并且没有明显的性能影响

我在网上搜索了一些关于优化这个场景的信息,但似乎找不到任何相关信息。 我找错地方了吗

我还想知道的是,这是否是一种可以接受的制作清单的方式?有没有更简单的方法?即避免使用大量的控制模板和样式


有人能帮忙吗?

我通常不会在选择项目时更改模板,最好在同一模板中使用视觉状态,这可能会避免重新创建一些在两种状态下都会重用的元素。但此选定模板不应导致加载挂起

我很惊讶你只看到了15件物品的明显延迟。我看不出你的模板有什么明显的错误,看起来很简单,但我不知道那些箭头和复选标记控件中有什么。您可能希望检查这些控件的xaml(或运行时的可视化树),以确保它们不必要地复杂

有几件事可以尝试减少初始渲染时间:

  • 在每个项目中使用视觉状态逐步显示内部元素。因此,如果这些箭头或复选标记控件是问题所在,那么您可能会让每个元素以折叠这些元素开始,然后在一段时间后使它们可见

  • 不要一次绑定整个列表,而是绑定到一个最初为空的列表,然后将每个项添加到dispatcher循环中,该循环允许UI在创建每个容器之间做出响应


  • 我通常不会在选择项目时更改模板,最好在同一模板中使用可视状态,这可能会避免重新创建一些在两种状态下都会重用的元素。但此选定模板不应导致加载挂起

    我很惊讶你只看到了15件物品的明显延迟。我看不出你的模板有什么明显的错误,看起来很简单,但我不知道那些箭头和复选标记控件中有什么。您可能希望检查这些控件的xaml(或运行时的可视化树),以确保它们不必要地复杂

    有几件事可以尝试减少初始渲染时间:

  • 在每个项目中使用视觉状态逐步显示内部元素。因此,如果这些箭头或复选标记控件是问题所在,那么您可能会让每个元素以折叠这些元素开始,然后在一段时间后使它们可见

  • 不要一次绑定整个列表,而是绑定到一个最初为空的列表,然后将每个项添加到dispatcher循环中,该循环允许UI在创建每个容器之间做出响应


  • 谢谢你的回答!我删除了TaskStyleSelector,并用绑定到值的控件替换了元素。使用datatriggers,我更改了每个元素的样式,这允许更快的速度。我仍然不满意,所以我将继续优化:)使用dispatcher循环没有多大帮助,因为我需要在处理列表之前显示列表。谢谢您的回答!我删除了TaskStyleSelector,并用绑定到值的控件替换了元素。使用datatriggers,我更改了每个元素的样式,这允许更快的速度。我仍然不满意,所以我将继续优化:)使用dispatcher循环没有多大帮助,因为我需要在处理列表之前显示列表。