Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug Silverlight DataGrid with Combobox rendering problem
11 replies. Latest Post by Saptarshi Chatterjee on November 9, 2009.
(0)
Saptarsh...
Member
0 points
7 Posts
10-21-2009 11:26 AM |
As you know that we have already implemented Silverlight application in our application, we need your help to resolve one issue that currently we are facing, actually this is a production bug. We are using Silverligh3 latest version. In our Silverlight page we have one data grid and inside that we have one dropdown list as a column and others are textboxes. The dropdown lists are attached with the data context using two way binding. Now in order to simulate the issue, add multiple rows (using front-end ‘Add Row’ custom button) on that data grid at runtime so that scrollbar is coming on the data grid, select data from combo boxes from first two rows, and after scrolling up and down for 2-3times causing combo boxes data disappeared from selected ones and it is appearing on rows where no values are selected earlier. But if you reload the page then everything is coming as before. And we have checked that the data context object is purely ok and this is a layout refreshing problem only. I do not know whether this is a bug of Silverlight or not, but as this is a production issue, I need your help urgently.
Sledge70
Contributor
5974 points
1,049 Posts
10-21-2009 11:36 AM |
This is a known issue with controls using the virtualisedstackpanel.
If there aren't many rows in your datagrid you can fix this by turning virtualisation off in your DataGrid declaration:
<data:DataGrid VirtualizingStackPanel.VirtualizationMode="Standard" />
10-22-2009 5:30 AM |
Thanks for your reply. I have incorporated the VirtualizingStackPanel.VirtualizationMode="Standard" as per your suggestion, but it is giving us the same rendering issue. Below is my datagrid code:
<basics:TabItem Header="Financier" x:Name="tabFinancier" IsSelected="False"> <Grid x:Name="grd2" Width="739"> <data:DataGrid Margin="18,0,18,18" VirtualizingStackPanel.VirtualizationMode="Standard" x:Name="dtgFinancier" AutoGenerateColumns="False" ItemsSource="{Binding Mode=TwoWay, Path=PropGeneralProposal_FinancierDetails_Col}" Tag="PropGeneralProposal_FinancierDetails_Col"> <data:DataGrid.Columns> <data:DataGridTemplateColumn Header="Agreement Type"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox x:Name="cmbAgreementType" DataContext="{Binding Mode=TwoWay, Path=PropFinancierDetails_AgreementType}" Loaded="SetDataForCombo" SelectionChanged="SetComboData" Height="24" Width="120" /> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> </Grid></basics:TabItem>
Am I missing something? I am also attaching you the full code for my xaml. From my xaml.vb I am adding atleast 15 blank rows to the above datagrid collection object named "PropGeneralProposal_FinancierDetails_Col" in order to simulate the issue. Pls help.
10-22-2009 5:37 AM |
Hmmm that has fixed it for me in the past.
You could try turning off virtualisation on the combobox using the same method as it also uses the virtualised stackpanel.
10-22-2009 5:59 AM |
Thanks for your reply. I have tried that, but it also did not work. Pls suggest what to do. This is a serious issue that I am facing in production with silverlight application.
Mog Lian...
All-Star
15998 points
1,553 Posts
10-25-2009 10:23 PM |
Hi,
Thanks for report. This is an known issue that virtualizing doesn't initialize all control states while reusing controls.
Currently, an workaround is set binding on combobox.selecteditem. when loading combobox, the binding will recalculate value and initialize selection.
Thanks,
10-27-2009 12:57 AM |
Thanks for your reply. Can you please explain in detail as where should I put the initialization code for the workaround? I have checked with combobox Loaded, LayoutUpdate event etc but it did not work, the same rendering issue is there. Please share me the code so that I can use. If you need any extra information I am ready to share with you.
11-02-2009 2:28 AM |
Is this a limitation of Microsoft silverlight product that we should not use Combobox inside datagrid or any alternative is there that really helped me in this situation? If no workaround is there, can anybody let me know that when Microsoft is about to release this as a patch? This patch is urgent as if we are implementing silverlight in production environment then customer will not listen that this sophisticated product have this kind of limitation!
11-02-2009 2:55 AM |
I find a way to close virtualizing feature, set combobox.itemspanel to stackpanel like this
<ComboBox > <ComboBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel/> </ItemsPanelTemplate> </ComboBox.ItemsPanel> </ComboBox>
Please try if this works.
11-02-2009 9:19 AM |
Thanks for your reply. I have simulated the problem in a test page which I have uploaded in this forum. As per your suggestion I have added the code but I doubt whether I have done it properly. Please check the code as after incorporating the StackPanel also it behaves the same way. You will find the source code for Page1.xaml and the Page1.xaml.vb below in this page. Please review and let me know why virtualization is still active.
Page1.xaml -------------- <navigation:Page x:Class="SLClientApp.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Page1 Page"> <Grid x:Name="LayoutRoot"> <data:DataGrid Margin="18,0,18,18" VirtualizingStackPanel.VirtualizationMode="Standard" x:Name="dtgTestGrid" ItemsSource="{Binding Mode=TwoWay, Path=TestDataCol}" AutoGenerateColumns="False" > <data:DataGrid.Columns> <data:DataGridTemplateColumn Header="Test Combo"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox VirtualizingStackPanel.VirtualizationMode="Standard" Loaded="SetDataForCombo" x:Name="cmbTestCombo" Height="24" Width="120" > <ComboBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel/> </ItemsPanelTemplate> </ComboBox.ItemsPanel> </ComboBox> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> </Grid> </navigation:Page> Page1.xaml.vb ------------- Imports System.Collections.ObjectModel Partial Public Class Page1 Inherits Page Public objTestClassCol As New TestClassCol Public Sub New() InitializeComponent() End Sub 'Executes when the user navigates to this page. Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs) End Sub Private Sub SetDataForCombo(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) For iCount = 1 To 5 CType(sender, System.Windows.Controls.ComboBox).Items.Add("Value" + CStr(iCount)) Next iCount End Sub Private Sub Page1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded LayoutRoot.DataContext = objTestClassCol For iCount = 1 To 30 objTestClassCol.TestDataCol.Add(New TestClass) Next End Sub End Class Public Class TestClass Private strLVTestData As String Public Property TestData() As String Get Return strLVTestData End Get Set(ByVal value As String) strLVTestData = value End Set End Property End Class Public Class TestClassCol Private objLVTestData As New ObservableCollection(Of TestClass) Public Property TestDataCol() As ObservableCollection(Of TestClass) Get Return objLVTestData End Get Set(ByVal value As ObservableCollection(Of TestClass)) objLVTestData = value End Set End Property End Class
11-02-2009 9:43 PM |
The solution I mentioned before is trying to disable combobox's virtualizing function, however, from your code, I realized that this is caused by datagrid's virtualizing, so it won't work.
To keep the selection state, you could use two way binding bind to Combobox.SelectedItem property. please try this xaml
<Grid x:Name="LayoutRoot"> <!--Two way binding on itemssource is not necessary--> <data:DataGrid Margin="18,0,18,18" x:Name="dtgTestGrid" ItemsSource="{Binding TestDataCol}" AutoGenerateColumns="False" > <data:DataGrid.Columns> <data:DataGridTemplateColumn Header="Test Combo"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <!--Set twoway binding on selecteditem property to save the state to viewmodel--> <ComboBox x:Name="cmbTestCombo" Loaded="SetDataForCombo" SelectedItem="{Binding TestData, Mode=TwoWay}" Height="24" Width="120" > </ComboBox> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> </Grid>
11-09-2009 5:04 AM |
Hi Mog, thanks for your excellent support as the issue got resolved.