DataGrid inside a TabControl problem

Nov 2, 2008 at 2:05 AM
I'm having a problem with a datagrid (v1 release) inside a tabcontrol. I have included a sample demonstrating my problem below. In the sample, I create a tab control with two tabs. Both datagrids are set to the same ItemsSource in the tab control's Loaded event and the XAML for each is the same. However, the datagrid in the first tab has no scrollbar (as expected) while the datagrid in the second tab does have a scrollbar and a wider layout.

The second tab has a button labeled "Reload DataGrid". Press that button to reload the datagrid and will notice that it now looks just like the first datagrid!

What's going on? Is there something I am doing wrong?

Here is the XAML:
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="400">
    <Grid>
        <TabControl TabStripPlacement="Left" Loaded="TabControl_Loaded">
            <TabItem Header="FirstTabItem">
                    <toolkit:DataGrid x:Name="firstDataGrid"
                                  AutoGenerateColumns="False">
                        <toolkit:DataGrid.Columns>
                            <toolkit:DataGridTextColumn Header="Column1"
                                                    Binding="{Binding Path=Column1}"
                                                    Width="*" />
                            <toolkit:DataGridTextColumn Header="Column2"
                                                    Binding="{Binding Path=Column2}"
                                                    Width="*" />
                            <toolkit:DataGridTextColumn Header="Column3"
                                                    Binding="{Binding Path=Column3}"
                                                    Width="Auto" />
                        </toolkit:DataGrid.Columns>
                    </toolkit:DataGrid>

            </TabItem>
            <TabItem Header="SecondTab">
                <DockPanel>
                    <Button HorizontalAlignment="Center" Click="Button_Click"
                            DockPanel.Dock="Bottom">
                        <TextBlock Text="Refresh DataGrid"/>
                    </Button>
                    <toolkit:DataGrid x:Name="secondDataGrid"
                                  AutoGenerateColumns="False">
                        <toolkit:DataGrid.Columns>
                            <toolkit:DataGridTextColumn Header="Column1"
                                                    Binding="{Binding Path=Column1}"
                                                    Width="*" />
                            <toolkit:DataGridTextColumn Header="Column2"
                                                    Binding="{Binding Path=Column2}"
                                                    Width="*" />
                            <toolkit:DataGridTextColumn Header="Column3"
                                                    Binding="{Binding Path=Column3}"
                                                    Width="Auto" />
                        </toolkit:DataGrid.Columns>
                    </toolkit:DataGrid>
                </DockPanel>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

And here is the code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        List<DataGridRow> dataArray;

        public Window1()
        {
            InitializeComponent();
            this.dataArray = new List<DataGridRow> {
                new DataGridRow { Column1="aaa", Column2="bbb", Column3=1 },
                new DataGridRow { Column1="cccccccc", Column2="dddddddddddd", Column3=2 }
            };
        }

        private void TabControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.firstDataGrid.ItemsSource = dataArray;
            this.secondDataGrid.ItemsSource = dataArray;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.secondDataGrid.ItemsSource = null;
            this.secondDataGrid.ItemsSource = this.dataArray;
        }
    }

    public class DataGridRow
    {
        public string Column1
        {
            get;
            set;
        }

        public string Column2
        {
            get;
            set;
        }

        public long Column3
        {
            get;
            set;
        }
    }
}

Coordinator
Nov 6, 2008 at 7:48 PM
This is a bug and will be addressed in the next release.  For a workaround, you can do a type of lazy loading of the DataGrids which would mitigate the issue.  You can listen to TabControl.SelectionChanged and set the DataGrid.ItemsSource accordingly (of course you can optimize by checking if it has been set already).
Dec 28, 2008 at 3:42 PM
Edited Dec 28, 2008 at 3:42 PM
Hi vinsibal,
I've encountered a similar problem - when creating a datagrid, although specifying the grid's width (which should fit the window contains that grid),the grid is shown with horizontal scroll bar,
and when scrolling it to the right edge, the scroll disappears...(what I would expect to happen instead is that the scroll would not be visible in the first place)

Thanks in advance
Regev