渲染多个 DataGrid 时 Silverlight UI 冻结
当数据绑定/渲染数据网格时,我遇到了 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该考虑使用数据分页器一次仅显示一定数量的行。
You should consider using a data pager to only show a certain amount of rows at one time.