代码之家  ›  专栏  ›  技术社区  ›  David

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

  •  2
  • David  · 技术社区  · 16 年前

    我在屏幕上有大量的元素(我将其表示为控件)。从数字上看,它就在附近 ,但确切数字取决于浏览器窗口的大小。

    每个元素最终将显示信息(文本块、图像)并具有一些鼠标交互(工具提示、用于切换和拖放的鼠标事件)。乍一看,它可能类似于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 < elementsRequired; i++)
    {
        var item = new MyElement();
        // Set Canvas.LeftProperty and Canvas.TopProperty to a unique position
        ElementsArea.Children.Add(item);                    
    }
    

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

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


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

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

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

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


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

    有没有办法解决这个问题?

    1 回复  |  直到 16 年前
        1
  •  0
  •   David    16 年前

    经过反复试验,我终于找到了罪魁祸首。

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

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