渲染多个 DataGrid 时 Silverlight UI 冻结

发布于 2024-12-05 16:03:04 字数 5541 浏览 1 评论 0原文

当数据绑定/渲染数据网格时,我遇到了 Silverlight UI(实际上是浏览器)冻结的问题。我已经能够使用下面的代码重现该问题,该代码使用 4 个网格。实际上,我们将使用 4 个以上的网格。

我发现如果我只有一个网格和更多行(例如 3000),一切都很好。

当四个数据网格尝试绑定/渲染时,它们之间似乎存在争用,从而导致 UI 锁定。

这是 silverlight 的已知问题吗?有哪些解决方法?

重现问题的代码

数据对象:

public class DataObject
{
    public string Column0 { get; set; }
    public string Column1 { get; set; }
    public string Column2 { get; set; }
    ...
    public string Column30 { get; set; }

    public DataObject()
    {
        Random r = new Random(DateTime.Now.Millisecond);

        Column0 = r.Next(1000).ToString();
        Column1 = r.Next(1000).ToString();
        Column2 = r.Next(1000).ToString();
        ...
        Column30 = r.Next(1000).ToString();
    }
}

代码隐藏:

public partial class MainPage : UserControl
{
    private ObservableCollection<DataObject> _data = new ObservableCollection<DataObject>();

    public MainPage()
    {
        InitializeComponent();

        PopulateData();

        DataContext = _data;
    }

    private void PopulateData()
    {
        for (int i = 0; i < 300; i++)
        {
            _data.Add(new DataObject());
        }
    }

    public ObservableCollection<DataObject> Data
    {
        get { return _data; }
        set { _data = value; }

    }
}

XAML:

<UserControl x:Class="SilverlightGridTest.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sdk="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">

<Grid x:Name="LayoutRoot" Background="White">
    <ScrollViewer>
        <StackPanel>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
        </StackPanel>
    </ScrollViewer>
</Grid>

I'm experiencing issues with the Silverlight UI (and indeed the browser) freezing when databinding/rendering datagrids. I have been able to reproduce the issue with the code below which uses 4 grids. In practice we will be using more than 4 grids.

I've found that if I only have a single grid and many more rows (e.g. 3000) everything is fine.

It looks like there there is contention between the four datagrids when they are trying to bind/render which is causing the UI to lockup.

Is this a known issue with silverlight? What work arounds are there?

Code to reproduce problem

Data object:

public class DataObject
{
    public string Column0 { get; set; }
    public string Column1 { get; set; }
    public string Column2 { get; set; }
    ...
    public string Column30 { get; set; }

    public DataObject()
    {
        Random r = new Random(DateTime.Now.Millisecond);

        Column0 = r.Next(1000).ToString();
        Column1 = r.Next(1000).ToString();
        Column2 = r.Next(1000).ToString();
        ...
        Column30 = r.Next(1000).ToString();
    }
}

Codebehind:

public partial class MainPage : UserControl
{
    private ObservableCollection<DataObject> _data = new ObservableCollection<DataObject>();

    public MainPage()
    {
        InitializeComponent();

        PopulateData();

        DataContext = _data;
    }

    private void PopulateData()
    {
        for (int i = 0; i < 300; i++)
        {
            _data.Add(new DataObject());
        }
    }

    public ObservableCollection<DataObject> Data
    {
        get { return _data; }
        set { _data = value; }

    }
}

XAML:

<UserControl x:Class="SilverlightGridTest.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sdk="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">

<Grid x:Name="LayoutRoot" Background="White">
    <ScrollViewer>
        <StackPanel>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:DataGrid Grid.Row="0"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ItemsSource="{Binding}" 
                  Width="800"
                  Height="700"
                  AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>
                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Binding="{Binding Column0, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column1, Mode=TwoWay}" IsReadOnly="True" />
                    <sdk:DataGridTextColumn Binding="{Binding Column2, Mode=TwoWay}" IsReadOnly="True" />
                    ...
                    <sdk:DataGridTextColumn Binding="{Binding Column30, Mode=TwoWay}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
        </StackPanel>
    </ScrollViewer>
</Grid>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨小墨 2024-12-12 16:03:04

您应该考虑使用数据分页器一次仅显示一定数量的行。

You should consider using a data pager to only show a certain amount of rows at one time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文