Hi,
I'm using the grid to bind to an ICollectionView. I've added a behaviour on the grid so that it binds to the CurrentItem.When the CurrentItem changes, it will select the corresponding row and call ScrollIIntoView on it. Vice-versa selecting a row calls MoveCurrentTo() on the ICollectionView.
I've used that in some other part of the application and it works great. However, on this new grid I do the following operations (the grid uses TemplateColumns):
- _myCollectionView.Clear();
- var savedPosition = _myCollectionView.CurrentPosition;
- foreach(...) { _myCollectionView.Add(myObject); }
- _myCollectionView.MoveCurrentToPosition(savedPosition);
Unfortunately the current item is selected (the row is coloured), but it's not brought into view.
Now if I replace the last instruction by:
- SynchronizationContext.Current.Post((o) => _myCollectionView.MoveCurrentToPosition(savedPosition));
Then it brings the current item to view.
Am I doing something wrong or is this a bug of the grid?
PS: If I can I'll try to create a test project.
Cheers.
Could you post the code that you are calling to scroll the row into view?
Could you also provide information about your rows / columns / layouts - are there column layouts, etc.
Thanks,
Thanks for the quick reply. Here's a copy/paste of the grid itself from production code
<igGrid:XamWebGrid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemsSource="{Binding ReferencePoints}" Behaviors:XamWebGridCurrentItemBindingBehavior.CurrentCollectionView="{Binding ReferencePoints}" UseLayoutRounding="True" AutoGenerateColumns="False" CellStyle="{StaticResource CellControlStyleForColouredRows}" IsAlternateRowsEnabled="True" RowHover="Row" ColumnLayoutHeaderVisibility="Never" RowHeight="Dynamic" ColumnWidth="*" HeaderVisibility="Visible" > <igGrid:XamWebGrid.AddNewRowSettings> <igGrid:AddNewRowSettings AllowAddNewRow="None" /> </igGrid:XamWebGrid.AddNewRowSettings> <igGrid:XamWebGrid.RowSelectorSettings> <igGrid:RowSelectorSettings EnableRowNumbering="False" /> </igGrid:XamWebGrid.RowSelectorSettings> <igGrid:XamWebGrid.SortingSettings> <igGrid:SortingSettings AllowMultipleColumnSorting="True" AllowSorting="True" ShowSortIndicator="True" /> </igGrid:XamWebGrid.SortingSettings> <igGrid:XamWebGrid.SelectionSettings> <igGrid:SelectionSettings CellClickAction="SelectRow" CellSelection="None" ColumnSelection="None" RowSelection="Single" /> </igGrid:XamWebGrid.SelectionSettings> <igGrid:XamWebGrid.ColumnResizingSettings> <igGrid:ColumnResizingSettings AllowDoubleClickToSize="True" AllowColumnResizing="Immediate" /> </igGrid:XamWebGrid.ColumnResizingSettings> <igGrid:XamWebGrid.Columns> <igGrid:TemplateColumn Key="EditButton" IsReadOnly="True" IsResizable="False" Width="SizeToCells" IsSortable="False" MinimumWidth="5" HeaderStyle="{StaticResource HeaderCellControlStyleForNoSorting}"> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <Button Command:Click.Command="{Binding Path=Value, Source={StaticResource EditSymbolCommand}}" Command:Click.CommandParameter="{Binding }" Behaviors:ToolTipBindingBehavior.ToolTipContent="{Binding Resource.ReferencePointEditSymbol, Source={StaticResource LocalizedStrings}}" Margin="0" Padding="3,0,3,0" > <Image Source="{Binding Configuration, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </Button> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <Image Source="{Binding Configuration, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> </igGrid:TemplateColumn> <igGrid:TemplateColumn Key="RenameButton" IsReadOnly="True" IsResizable="False" Width="SizeToCells" IsSortable="False" MinimumWidth="5" HeaderStyle="{StaticResource HeaderCellControlStyleForNoSorting}"> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <Button Command:Click.Command="{Binding Path=Value, Source={StaticResource RenameCommand}}" Command:Click.CommandParameter="{Binding }" Behaviors:ToolTipBindingBehavior.ToolTipContent="{Binding Resource.ReferencePointRename, Source={StaticResource LocalizedStrings}}" Margin="0" Padding="3,0,3,0" > <Image Source="{Binding GroupRename, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </Button> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <Image Source="{Binding GroupRename, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> </igGrid:TemplateColumn> <igGrid:TemplateColumn Key="DeleteButton" IsReadOnly="True" IsResizable="False" Width="SizeToCells" IsSortable="False" MinimumWidth="5" HeaderStyle="{StaticResource HeaderCellControlStyleForNoSorting}"> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <Button Command:Click.Command="{Binding Path=Value, Source={StaticResource DeleteCommand}}" Command:Click.CommandParameter="{Binding }" Behaviors:ToolTipBindingBehavior.ToolTipContent="{Binding Resource.DeleteReferencePoint, Source={StaticResource LocalizedStrings}}" Margin="8,0,0,0" Padding="3,0,3,0" > <Image Source="{Binding Delete, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </Button> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <Image Source="{Binding Delete, Source={StaticResource ImagesPath}}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="12" Stretch="Uniform"/> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> </igGrid:TemplateColumn> <igGrid:TemplateColumn Key="SymbolAddress" Width="SizeToCells" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <Image Source="{Binding SymbolAddress}" Stretch="None" Margin="5,0,5,0" /> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding Resource.ReferencePointHeaderSymbol, Source={StaticResource LocalizedStrings}}" /> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> </igGrid:TemplateColumn> <igGrid:TextColumn Key="Name" Width="SizeToCells"> <igGrid:TextColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding Resource.ReferencePointHeaderName, Source={StaticResource LocalizedStrings}}" /> </DataTemplate> </igGrid:TextColumn.HeaderTemplate> </igGrid:TextColumn> <igGrid:TemplateColumn Key="Filler" IsReadOnly="True" IsResizable="False" Width="*" HeaderText=" "> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> </Grid> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> </igGrid:XamWebGrid.Columns> </igGrid:XamWebGrid>
Here's a copy/paste of the behaviour that keeps the current row in synch with the current item:
public static class XamWebGridCurrentItemBindingBehavior { public static readonly DependencyProperty CurrentCollectionViewProperty = DependencyProperty.RegisterAttached("CurrentCollectionView", typeof(ICollectionView), typeof(XamWebGridCurrentItemBindingBehavior), new PropertyMetadata(OnCurrentCollectionViewSetCallback)); public static ICollectionView GetCurrentCollectionView(DependencyObject obj) { return (ICollectionView)obj.GetValue(CurrentCollectionViewProperty); } public static void SetCurrentCollectionView(DependencyObject obj, ICollectionView value) { obj.SetValue(CurrentCollectionViewProperty, value); } private static void OnSelectedRowsCollectionChanged(object sender, SelectionCollectionChangedEventArgs<SelectedRowsCollection> e) { var grid = (DependencyObject)sender; var collectionView = GetCurrentCollectionView(grid); if (collectionView != null && e.NewSelectedItems.Count > 0) { collectionView.MoveCurrentTo(e.NewSelectedItems[0].Data); } } private static void OnActiveCellChanging(object sender, ActiveCellChangingEventArgs e) { e.Cancel = true; } private static void OnCurrentChanged(XamWebGrid grid) { var collectionView = GetCurrentCollectionView(grid); if (collectionView != null) { if (collectionView.CurrentItem == null) { grid.SelectionSettings.SelectedRows.Clear(); } else { Row rowToSelect = grid.Rows.FirstOrDefault(r => r.Data == collectionView.CurrentItem); if (rowToSelect == null) { grid.SelectionSettings.SelectedRows.Clear(); } else { if (grid.SelectionSettings.SelectedRows.Count != 1 || ( grid.SelectionSettings.SelectedRows.Count == 1 && grid.SelectionSettings.SelectedRows[0] != rowToSelect ) ) { rowToSelect.IsSelected = true; grid.ScrollCellIntoView(rowToSelect.Cells[0]); } } } } } private static void OnCurrentCollectionViewSetCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { var oldCollection = (ICollectionView)e.OldValue; var newCollection = (ICollectionView)e.NewValue; var grid = (XamWebGrid)d; if (oldCollection != null) { oldCollection.CurrentChanged -= (o, ev) => OnCurrentChanged(grid); } if (newCollection != null) { newCollection.CurrentChanged += (o, ev) => OnCurrentChanged(grid); } grid.SelectedRowsCollectionChanged -= OnSelectedRowsCollectionChanged; grid.ActiveCellChanging -= OnActiveCellChanging; grid.SelectedRowsCollectionChanged += OnSelectedRowsCollectionChanged; grid.ActiveCellChanging += OnActiveCellChanging; } }
And in my code what I do on an update is:
var savedPosition = _referencePoints.CurrentPosition; using (_referencePoints.DeferRefresh()) { _referencePoints.Clear(); foreach (var referencePoint in referencePoints) { _referencePoints.Add(new ReferencePointWithAddress(referencePoint, _profileAddressHelperService, _profileService)); } } if (savedPosition < _referencePoints.Count) { SynchronizationContext.Current.Post((o) => _referencePoints.MoveCurrentToPosition(savedPosition), null); }