I have some code like this:
<igControls:XamTabControl ItemsSource="{Binding PricingTables, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
SelectedIndex="{Binding SelectedIndex}" Theme="Office2013" local:SendMouseWheelToParent.IsSendingMouseWheelEventToParent="True"> <igControls:XamTabControl.PostTabItemContent> <Button Grid.Column="1" Content="Add" ToolTip="Create a new conditional pricing table" Command="{Binding AddConditionalPriceTableCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" /> </igControls:XamTabControl.PostTabItemContent> <TabControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding PricingTableName}" /> </DataTemplate> </TabControl.ItemTemplate> <TabControl.ContentTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid Grid.Column="1" Margin="5"> <!-- This is the sidebar --> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <CheckBox Grid.Row="0" IsChecked="{Binding IsIncluded}" Content="Use This Table" /> <CheckBox Grid.Row="1" IsChecked="{Binding DisplayLevelIndices}" VerticalAlignment="Center" VerticalContentAlignment="Center">Display Level Indices</CheckBox> <Button Grid.Row="3" Margin="0,10,0,0" HorizontalAlignment="Left" Command="{Binding DataContext.RemovePricingTableCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}} }" CommandParameter="{Binding}" ToolTip="Deletes this conditional pricing table permanently" ToolTipService.ShowOnDisabled="True"> <StackPanel Orientation="Horizontal"> <Image Source="{StaticResource DeleteIcon}" Stretch="Uniform" Height="12" Margin="0,0,5,0" /> <TextBlock VerticalAlignment="Center">Delete This Table</TextBlock> </StackPanel> </Button> </Grid> <Grid Grid.Column="0" FlowDirection="LeftToRight" HorizontalAlignment="Left"> <igControls:XamDataGrid DataSource="{Binding ConditionalPriceRows, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoFit="False" FieldLayoutInitialized="DataPresenterBase_OnFieldLayoutInitialized" Tag="{Binding ExternalReadOnly, Mode=OneTime}"> <i:Interaction.Behaviors> <local:EditModeOnTypeBehavior /> <local:ClipboardBehavior PasteAddsRows="False" ShowErrorOnReadOnlyPaste="False" /> <local:CellUpdateDirtyBehavior /> </i:Interaction.Behaviors> <igControls:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoGenerateFields="True" AllowDelete="False" AllowAddNew="False" AllowFieldMoving="No" AllowClipboardOperations="All" RecordSelectorNumberStart="1" RecordSelectorNumberType="VisibleIndex" HeaderPrefixAreaStyle="{StaticResource HeaderPrefixStyle}" /> </igControls:XamDataGrid.FieldLayoutSettings> </igControls:XamDataGrid> </Grid> </Grid> </DataTemplate> </TabControl.ContentTemplate> </igControls:XamTabControl>
What I'm trying to do is have multiple tabs, each with their own data grid with different columns. What I'm seeing is that when the first tab is created, the grid has all the correct columns. When I create a new second tab, the columns are the same as the first tab's. It's like they are linked somehow. Also the FieldLayoutInitialized handler is not called on the second tab's grid creation. What am I doing wrong?
Hello Walter,
I am glad that you have found a behavior that works for you on this matter. It is likely that what is happening here is that the grid.DefaultFieldLayouts.Fields collection gets cleared prior to the grid making its check for the existing fields when creating the DataRecords, which will fire the FieldLayoutInitialized event, as this check will not find any suitable fields, and so a new FieldLayout will need to be created and initialized.
Please let me know if you have any other questions or concerns on this matter.
Sincerely,AndrewAssociate Developer
Using your suggestion I created a behavior that appears to work so far:
///
/// Behavior to reset the field layout of the grid when the selected tab changes /// internal class TabControlResetGridBehavior : Behavior { protected override void OnAttached () { this.AssociatedObject.SelectionChanged += this.SelectionChanged; base.OnAttached(); }
protected override void OnDetaching () { this.AssociatedObject.SelectionChanged -= this.SelectionChanged; base.OnDetaching(); }
private void SelectionChanged (Object sender, SelectionChangedEventArgs e) { var grid = Utilities.GetDescendantFromType(this.AssociatedObject, typeof(XamDataGrid), false) as XamDataGrid; if (grid == null || grid.DefaultFieldLayout == null) return;
grid.DefaultFieldLayout.Fields.Clear(); } }
Clearing the field layout will trigger the OnFieldLayoutInitialized event.
Thank you for your post.
You are correct in that these XamDataGrid's that exist in your XamTabControl's ContentTemplate are linked. They are linked in that they are actually the same exact instance of the XamDataGrid. You can see this by getting the XamDataGrid on your selected tab and checking its hash-code. It will be the same each time. This happens because the elements that are placed in the XamTabControl's ContentTemplate are reused, tab-to-tab, and unless bound, these elements will have the same values across each tab by default.
Regarding the FieldLayoutInitialized event not firing upon the second tab grid's "creation" (it is not really being 'created,' as it already exists), I feel this is likely due to the DataSource that you have bound to the grid. If this data source is a collection of the same type as used on your other tabs, the FieldLayout in your XamDataGrid will be reused, and so the FieldLayoutInitialized event will not fire for subsequent grids coming into view.
One thing you can do to get around this is to handle the SelectionChanged event of the XamTabControl. This will allow you to catch when a particular tab has been selected. Using the Infragistics.Windows.Utilities class and its static GetDescendantFromType or GetDescendantFromName methods, you can obtain your XamDataGrid from the XamTabControl and modify its FieldLayout there. The code to do this would look like the following, where 'tabControl' is the XamTabControl, and in the case of the GetDescendantFromName example, "XDG1" is the x:Name of the XamDataGrid:
XamDataGrid grid = Utilities.GetDescendantFromName(tabControl, "XDG1") as XamDataGrid;ORXamDataGrid grid = Utilities.GetDescendantFromType(tabControl, typeof(XamDataGrid), false) as XamDataGrid;
At this point, you can either directly modify the FieldLayout of your obtained grid and modify the fields that are shown for that particular FieldLayout. Note, that this will not work in the SelectionChanged event for the very first selected tab at the start of your application, as the grid will not be loaded at that point, and so you will likely want to continue with the FieldLayoutInitialized event for that part, at least.