当有许多控件时,Silverlight中的速度减慢(通常为滚动条或UI)

当有许多控件时,Silverlight中的速度减慢(通常为滚动条或UI),silverlight,controls,themes,silverlight-2.0,performance,Silverlight,Controls,Themes,Silverlight 2.0,Performance,我想了解Silverlight的工作原理-目前我想我需要更多地了解UI事件调度和控件重新绘制是如何完成的,以便为以下问题找到解决方案或折衷方案: 我在屏幕上有大量的元素(我将其表示为控件)。从数字上看,它大约在300左右,尽管确切的数字取决于浏览器窗口的大小 每个元素最终将显示信息(文本块、图像)并具有一些鼠标交互(工具提示、用于切换和拖放的鼠标事件)。乍一看,它可能类似于DataGrid,但不幸的是它不是(它是一个无限滚动的非矩形曲面)。但是现在每个元素只是一个用户控件,里面只有一个矩形 &l

我想了解Silverlight的工作原理-目前我想我需要更多地了解UI事件调度和控件重新绘制是如何完成的,以便为以下问题找到解决方案或折衷方案:

我在屏幕上有大量的元素(我将其表示为控件)。从数字上看,它大约在300左右,尽管确切的数字取决于浏览器窗口的大小

每个元素最终将显示信息(文本块、图像)并具有一些鼠标交互(工具提示、用于切换和拖放的鼠标事件)。乍一看,它可能类似于DataGrid,但不幸的是它不是(它是一个无限滚动的非矩形曲面)。但是现在每个元素只是一个用户控件,里面只有一个矩形

<UserControl x:Class="MyElement" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  Width="49" Height="49">
    <Grid>
        <Rectangle x:Name="Border" Stroke="Black" Fill="White" />
    </Grid>
</UserControl>

for(int i=0;i

创建300个这样的控件并将它们放到画布(或网格)上需要花费4秒的时间才能完成。然而,由于这个操作很少进行,我对它的关注程度不如下一个问题

一旦控制被放置,CPU是正常的(0%),但是尝试使用一个不相关的滚动条(一个没有事件的滚动条)会显示出很大的延迟-阴囊拇指难以跟上鼠标。如果我增加/减少元素的数量,滚动条延迟会相应地改变


在假设canvas元素(通常允许元素溢出)正在进行一些剪切计算的情况下,我尝试为画布定义一个剪切矩形,将滚动条完全移出画布(移动到另一个布局树中),并将画布更改为网格(所有300个元素都在中间重叠)。我还测试了将元素的可视性更改为Collasped,但没有效果

我也尝试过替换元素——只创建一个矩形或一个图像可以降低速度,但只达到我所期望的程度,因为树上的元素更少(MyElement是3个控件、UserControl、Grid和rectangle,而不是1个)

假设某个Find方法在到达滚动条之前必须横穿所有300个元素,我试图更改XAML文件中声明的顺序,但没有成功

最后,我尝试在元素和整个画布上将IshitteVisible和IsEnabled设置为false,但没有效果


据我所知,我有大量但完全合理数量的静态控件,它们通常不使用任何CPU,但当我尝试与不相关的滚动条交互时,它们会在UI或渲染管道中造成某种交通堵塞

有没有办法解决这个问题


编辑:已找到初始原因,请参见下文。(添加主题标签)

通过反复试验,我终于找到了责任因素

我正在使用Silverlight工具箱中的主题化系统。当我动态创建许多控件(“窗口”和“对话框”)时,主题有ApplyMode=“Auto”,其中控件自动应用主题样式

无论出于何种原因,拖动滚动条控件的拇指会不断触发此操作,导致所有这些控件的样式信息都会更新,而不管它们位于何处或是否可见


不幸的是,我看不到任何快速的解决方案来关闭它,因为动态控件无处不在。我试图做的是将ApplyMode更改为仅用于滚动条的一次,但是这似乎不起作用。我最好的猜测是滚动条正在为每一次更改动态创建一些控件-对此有任何见解吗通过反复试验,我终于找到了责任所在

我正在使用Silverlight工具箱中的主题化系统。当我动态创建许多控件(“窗口”和“对话框”)时,主题有ApplyMode=“Auto”,其中控件自动应用主题样式

无论出于何种原因,拖动滚动条控件的拇指会不断触发此操作,导致所有这些控件的样式信息都会更新,而不管它们位于何处或是否可见

不幸的是,我看不到任何快速的解决方案来关闭它,因为动态控件无处不在。我试图做的是将ApplyMode更改为仅用于滚动条的一次,但是这似乎不起作用。我最好的猜测是滚动条正在为每一次更改动态创建一些控件-对此有任何见解吗?

for (int i = 0; i < elementsRequired; i++)
{
    var item = new MyElement();
    // Set Canvas.LeftProperty and Canvas.TopProperty to a unique position
    ElementsArea.Children.Add(item);                    
}