Hello I am pretty new to using Infragistics and have been tasked to take over code that has been written by a previous developer.Based on my observations, this developer implemented a custom Infragistics XamDataGrid that allows one to bind to the SelectedItems property as the SelectedItems property does not allow binding by default according to him,.
Preview of code:
<CustomControls:BSIXamDataGrid x:Uid="xamDataGridCam" x:Name="xamDataGridCam" DataSource="{Binding QueryItems}" BindableSelectedItems="{Binding SelectedItems, Mode=TwoWay}" GroupByAreaLocation="None" GotKeyboardFocus="xamDataGridCam_GotKeyboardFocus" AutoFit="True" Grid.Row="4" VerticalContentAlignment="Stretch" ScrollingMode="Immediate" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.CanContentScroll="True" VerticalAlignment="Stretch" RecordsInViewChanged="xamDataGridCam_RecordsInViewChanged" RecordFilterDropDownPopulating="xamDataGridCam_RecordFilterDropDownPopulating" AssigningFieldLayoutToItem="xamDataGridCam_AssigningFieldLayoutToItem">
There seems to be a bug where if I try to navigate through the rows in a table using the arrow keys, it will only go to the next row then go back to the previous like so:
Could anyone please help me understand what's possibly going on? Thanks in advance!
Hello Shawn,
Thank you for contacting Infragistics. What happens when you remove BindableSelectedItems="{Binding Select .."? Does this fix the issue?
Please note that we added a way to bind to selected items called SelectedDataItems, added in 2014 in our Volume 2 package. I highly recommended that you migrate towards implementing by removing the custom implementation if it is feasible. Do you know when and if the custom implementation was only for this very requirement?
Let me know if you have any questions.
Hi Michael,
Removing that does not solve the issue and only adds the problem of my application not recognizing that a row has been selected. As for migrating to the newer package, I do not think that is feasible at this moment in time. From my knowledge this custom class has been implemented a couple of months ago and is shown below:
using Infragistics.Windows.DataPresenter; using Infragistics.Windows.DataPresenter.Events; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; namespace Vdi.VideoClient.SoftClient.CustomControls { /// <summary> /// The BSIXamDataGrid is a custom Infragistics XamDataGrid that allows one to bind to the SelectedItems property /// By default, the SelectedItems property does not allow binding. /// This class implements a BindableSelectedItems property which can be bound to a property in your ViewModel then manipulated as required /// from the ViewModel. /// The result is a XamDataGrid that appropriately displays highlights for when a record is selected. /// </summary> public class BSIXamDataGrid : XamDataGrid { public static readonly DependencyProperty BindableSelectedItemsProperty = DependencyProperty.Register("BindableSelectedItems", typeof(IEnumerable), typeof(BSIXamDataGrid)); public IEnumerable BindableSelectedItems { get { return (IEnumerable)GetValue(BindableSelectedItemsProperty); } set { SetValue(BindableSelectedItemsProperty, value); } } private void BindableSelectedItemsPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { this.SelectedItemsChanged -= new EventHandler<SelectedItemsChangedEventArgs>(BSIXamDataGrid_SelectedItemsChanged); this.ActiveRecord = null; if (!this.IsMouseOver) { this.SelectedItems.Records.Clear(); } if (args.NewValue != null) { foreach (var item in args.NewValue as IEnumerable) { this.SelectedItems.Records.Add(this.GetRecordFromDataItem(item, false)); } } this.SelectedItemsChanged += new EventHandler<SelectedItemsChangedEventArgs>(BSIXamDataGrid_SelectedItemsChanged); } public BSIXamDataGrid() : base() { this.SelectedItemsChanged += new EventHandler<SelectedItemsChangedEventArgs>(BSIXamDataGrid_SelectedItemsChanged); BindableSelectedItemsProperty.OverrideMetadata(typeof(BSIXamDataGrid), new FrameworkPropertyMetadata(BindableSelectedItemsPropertyChanged)); } void BSIXamDataGrid_SelectedItemsChanged(object sender, SelectedItemsChangedEventArgs e) { List<object> selectedItems = new List<object>(); foreach (object selectedItem in base.SelectedItems) { if (selectedItem is Cell) selectedItems.Add(((selectedItem as Cell).Record as DataRecord).DataItem); else if (selectedItem is DataRecord) selectedItems.Add((selectedItem as DataRecord).DataItem); } BindableSelectedItems = selectedItems as IEnumerable; } } }
Also I feel like this needs to be included as well:
<CustomControls:BSIXamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings x:Uid="igDP:FieldLayoutSettings_1" AllowRecordFixing="Top" HeaderPlacement="OnTopOnly" AllowDelete="False" RecordSelectorLocation="None" SelectionTypeRecord="ExtendedAutoDrag" AllowFieldMoving="WithinLogicalRow" HighlightAlternateRecords="False" AutoGenerateFields="False"/> </CustomControls:BSIXamDataGrid.FieldLayoutSettings>
Hello,
Thank you for following up. Which version of Infragistics is the application referencing? If it's higher than 14.2 you can simply use SelectedDataItems instead of the custom BindableSelectedItems property.
The version of Infragistics my application is licensed to use is:
Assembly InfragisticsWPF4.DataPresenter.v12.1, Version=12.1.20121.2286
I'm told by management that upgrading to a newer version isn't financially feasible at the moment so I would like to figure out a work-around for this issue.
I strongly encourage you to review the following blog that contains a sample ( at the bottom of the page) demonstrating a working scenario of a derived XamDataGrid with a custom "selecteditems" dependency property. The blog was written before 14.2 when SelectedDataItems wasn't available. If the issue still occurs with the following implementation let me know.
eg.
public class MyXamDataGrid : XamDataGrid { public static readonly DependencyProperty NewXDGSelectedItemsProperty = DependencyProperty.Register("NewXDGSelectedItems", typeof(IEnumerable), typeof(MyXamDataGrid)); public IEnumerable NewXDGSelectedItems { get { return (IEnumerable)GetValue(NewXDGSelectedItemsProperty); } set { SetValue(NewXDGSelectedItemsProperty, value); } } private void NewXDGSelectedItemsPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { this.SelectedItemsChanged -= new EventHandler<SelectedItemsChangedEventArgs>(MyXamDataGrid_SelectedItemsChanged); this.ActiveRecord = null; if (!this.IsMouseOver) { this.SelectedItems.Records.Clear(); } if (args.NewValue != null) { foreach (var item in args.NewValue as IEnumerable) { this.SelectedItems.Records.Add(this.GetRecordFromDataItem(item, false)); //(item as TestItem).IsSelected = true; } } this.SelectedItemsChanged += new EventHandler<SelectedItemsChangedEventArgs>(MyXamDataGrid_SelectedItemsChanged); } public MyXamDataGrid() :base() { this.SelectedItemsChanged += new EventHandler<SelectedItemsChangedEventArgs>(MyXamDataGrid_SelectedItemsChanged); NewXDGSelectedItemsProperty.OverrideMetadata(typeof(MyXamDataGrid), new FrameworkPropertyMetadata(NewXDGSelectedItemsPropertyChanged)); } void MyXamDataGrid_SelectedItemsChanged(object sender, SelectedItemsChangedEventArgs e) { List<object> selectedItems = new List<object>(); foreach (object selectedItem in base.SelectedItems) { if (selectedItem is Cell) selectedItems.Add(((selectedItem as Cell).Record as DataRecord).DataItem); else if (selectedItem is DataRecord) selectedItems.Add((selectedItem as DataRecord).DataItem); } NewXDGSelectedItems = selectedItems as IEnumerable; } }
Hi Michael,I have reviewed the blog along with the code and I can verify that the MyXamDataGrid is identical to mines "BSIXamDataGrid". I was not able to run the application as I do not have an extra license for Infragistics to use. However I do feel the problem may be in the xaml file that I have posted "QueryUserControl.xaml".
<CustomControls:BSIXamDataGrid x:Uid="xamDataGridCam" x:Name="xamDataGridCam" DataSource="{Binding QueryItems}" BindableSelectedItems="{Binding SelectedItems, Mode=TwoWay}" GroupByAreaLocation="None" GotKeyboardFocus="xamDataGridCam_GotKeyboardFocus" AutoFit="True" Grid.Row="4" VerticalContentAlignment="Stretch" ScrollingMode="Immediate" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.CanContentScroll="True" VerticalAlignment="Stretch" RecordsInViewChanged="xamDataGridCam_RecordsInViewChanged" RecordFilterDropDownPopulating="xamDataGridCam_RecordFilterDropDownPopulating" AssigningFieldLayoutToItem="xamDataGridCam_AssigningFieldLayoutToItem"> <CustomControls:BSIXamDataGrid.Resources> <Style x:Uid="Style_2" TargetType="{x:Type igDP:DataRecordCellArea}" BasedOn="{StaticResource DataRecordCellAreaStyle}"/> </CustomControls:BSIXamDataGrid.Resources> <CustomControls:BSIXamDataGrid.ViewSettings> <igDP:GridViewSettings x:Uid="igDP:GridViewSettings_1" Orientation="Vertical" HeightInInfiniteContainers="100000"/> </CustomControls:BSIXamDataGrid.ViewSettings> <!-- Turn off cell editing. --> <CustomControls:BSIXamDataGrid.FieldSettings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_1" CellMinWidth="50" AllowGroupBy="True" AllowEdit="False" CellClickAction="SelectRecord" AllowRecordFiltering="True" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="None"/> </CustomControls:BSIXamDataGrid.FieldSettings> <CustomControls:BSIXamDataGrid.FieldLayouts> <igDP:FieldLayout x:Uid="igDP:FieldLayout_1"> <igDP:Field x:Uid="ItemImage" Name="ItemImage" Label=" "> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_2" AllowResize="False" Width="Auto" AllowRecordFiltering="False" AllowGroupBy="False"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Name" Name="Name" Label="{DynamicResource QueryControlGridColumnName}" IsScrollTipField="True"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_3" AllowRecordFiltering="True" AllowGroupBy="False" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="None" /> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Code" Name="Code" Label="{DynamicResource QueryControlGridColumnCode}"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_4" AllowEdit="False" CellWidth="20" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="{x:Null}" /> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Building" Name="Building" Label="{DynamicResource QueryControlGridColumnBuilding}"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_5" AllowRecordFiltering="True" AllowGroupBy="False" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="None" /> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Room" Name="Room" Label="{DynamicResource QueryControlGridColumnRoom}"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_6" AllowRecordFiltering="True" AllowGroupBy="False" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="None" /> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Type" Name="Type" Label="{DynamicResource QueryControlGridColumnType}"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_7" AllowRecordFiltering="True" FilterOperandUIType="DropDownList" FilterOperatorDropDownItems="None" FilterOperatorDefaultValue="Contains" AllowGroupBy="False" /> </igDP:Field.Settings> </igDP:Field> <igDP:Field x:Uid="Manufacturer" Name="Manufacturer" Label="{DynamicResource QueryControlGridColumnManufacturer}"> <igDP:Field.Settings> <igDP:FieldSettings x:Uid="igDP:FieldSettings_8" AllowRecordFiltering="True" FilterOperandUIType="DropDownList" FilterOperatorDefaultValue="Contains" FilterOperatorDropDownItems="None" AllowGroupBy="False" /> </igDP:Field.Settings> </igDP:Field> </igDP:FieldLayout> </CustomControls:BSIXamDataGrid.FieldLayouts> <CustomControls:BSIXamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings x:Uid="igDP:FieldLayoutSettings_1" AllowRecordFixing="Top" HeaderPlacement="OnTopOnly" AllowDelete="False" RecordSelectorLocation="None" SelectionTypeRecord="ExtendedAutoDrag" AllowFieldMoving="WithinLogicalRow" HighlightAlternateRecords="False" AutoGenerateFields="False"/> </CustomControls:BSIXamDataGrid.FieldLayoutSettings> </CustomControls:BSIXamDataGrid>
I reproduced the behavior, it's definitely not anything in XAML that's causing it. The issue stems from updating NewXDGSelectedItems when grid's SelectedItemsChanged event is fired. I haven't been able to work around this. But you might be better off using a Behavior with your custom implementation. This was discussed here
I'm in the process of adding said Behavior in conjunction with my custom implementation but I'm having a bit of trouble. I believe this method fires as soon as the application launches when it really should run once the window containing the XamDataGrid is launched/opened:
protected override void OnAttached() { base.OnAttached(); Grid.SelectedItemsChanged += new System.EventHandler<Infragistics.Windows.DataPresenter.Events.SelectedItemsChangedEventArgs>(Grid_SelectedItemsChanged); SelectedItems.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedItems_CollectionChanged); }
The error is that the SelectedItems object appears to be null as it hasn't even been created in the first place: