I have a grid that has two comboboxes. One combox is used to select a data type (i.e. Account, Manager, etc,) the other combobox is populated with a list of values of the selected type (i.e. a list of accounts or a list of managers). When the user changes the datatype, I point the second combobox to a list on the viewmodel of appropriate values.
OK so everything works fine with that - the problem is that we serialize the rows in the grid when the user exits the app and de-serialize them then when the user logs in again (serialized as entities of their native type, not xamDataRows or XamSomethingElse). When I deserialize, the combobox settings are incorrect. This is expected as they are not saved. I tried using SaveCustomizations and LoadCustomizations however it does not work. I think what I need to do is loop through the rows on the grid and set the set the values manually. How do I do that? The xaml below shows the relevent portion of the grid. The method named ParameterScopeChanged is called when the FIRST combox is changed i.e. the user changes the type data to be displayed in the second combobox. It just finds the second combobox and sets its itemssource to the correct list on the viewmodel. Ideally, when the grid is loaded I would like to just be able to call this method on each row.
private void ParameterScopeChanged(object sender, RoutedEventArgs e) { // scopeCombo is a list of data types XamComboEditor scopeCombo = ((XamComboEditor)sender); DataRecord record = (DataRecord)scopeCombo.DataContext; CellValuePresenter cvp = CellValuePresenter.FromCell(record.Cells[1]);
if (cvp == null || scopeCombo.ComboBox == null) return;
// valueCombo is a list of values of the type specified by scopeCombo XamComboEditor valueCombo = (XamComboEditor)Infragistics.Windows.Utilities.GetDescendantFromType(cvp, typeof(XamComboEditor), false); ComboBoxItemsProvider provider = null;
if(valueCombo.ItemsProvider == null) { provider = new ComboBoxItemsProvider(); valueCombo.ItemsProvider = provider; } else provider = valueCombo.ItemsProvider;
provider.DisplayMemberPath = ""; switch (scopeCombo.ComboBox.SelectedValue.ToString()) { case "PIMCO": valueCombo.ItemsProvider = null; break;
case "Account": provider.ItemsSource = ViewModel.Accounts; break;
case "Strategy": provider.ItemsSource = ViewModel.Strategies; break; case "PM": provider.ItemsSource = ViewModel.PM_Names; provider.DisplayMemberPath = "Name"; provider.ValuePath = "Name"; break;
default: throw new Exception("Scope not recognised: " + scopeCombo.ComboBox.SelectedValue.ToString()); }
if (valueCombo.ItemsProvider != null && valueCombo.ItemsProvider.Items.Count > 0) valueCombo.SelectedIndex = 0; }
<igDP:XamDataGrid x:Name="CashParameterGrid" GroupByAreaLocation="None" DataSource="{Binding CashParameters}" ActiveDataItem="{Binding CashParameterGrid_ActiveDataItem, Mode=TwoWay}" Grid.Column="0" KeyDown="XamDataGrid_KeyDown" RecordsDeleting="OnParameterDeleting" InitializeTemplateAddRecord="InitParameter" RecordUpdating="CashParameterGrid_RecordUpdating" RecordUpdated="CashParameterGrid_RecordUpdated" RecordAdded="CashParameterGrid_RecordAdded" > <igDP:XamDataGrid.Resources> <ResourceDictionary> <igEditors:ComboBoxItemsProvider x:Key="ParameterItemsProvider"/> <Style x:Key="ParameterScopeStyle" TargetType="{x:Type igEditors:XamComboEditor}"> <Setter Property="ItemsProvider"> <Setter.Value> <igEditors:ComboBoxItemsProvider> <igEditors:ComboBoxItemsProvider.Items> <igEditors:ComboBoxDataItem DisplayText="PIMCO" Value="Pimco"/> <igEditors:ComboBoxDataItem DisplayText="Account" Value="Account"/> <igEditors:ComboBoxDataItem DisplayText="Strategy" Value="Strategy"/> <igEditors:ComboBoxDataItem DisplayText="PM" Value="PM"/> </igEditors:ComboBoxItemsProvider.Items> </igEditors:ComboBoxItemsProvider>
</Setter.Value> </Setter> <Setter Property="Value" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDP:CellValuePresenter}}, Path=Value}"></Setter> <EventSetter Event="SelectedItemChanged" Handler="ParameterScopeChanged"/> </Style> <Style x:Key="CashDefStyle" TargetType="{x:Type igEditors:XamComboEditor}"> <Setter Property="ItemsProvider"> <Setter.Value> <igEditors:ComboBoxItemsProvider> <igEditors:ComboBoxItemsProvider.Items> <igEditors:ComboBoxDataItem DisplayText="Pure Cash" Value="PureCash" /> <igEditors:ComboBoxDataItem DisplayText="Mod2a" Value="Mod2a" /> <igEditors:ComboBoxDataItem DisplayText="True Cash" Value="TrueCash"/> <igEditors:ComboBoxDataItem DisplayText="Mod True Cash" Value="ModTrueCash"/> <igEditors:ComboBoxDataItem DisplayText="Liquid Assets" Value="LiquidAssets"/> </igEditors:ComboBoxItemsProvider.Items> </igEditors:ComboBoxItemsProvider> </Setter.Value> </Setter> <Setter Property="Value" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDP:CellValuePresenter}}, Path=Value}"></Setter> </Style> <Style x:Key="ComboEditor" TargetType="{x:Type igEditors:XamComboEditor}"> <Setter Property="Value" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDP:CellValuePresenter}}, Path=Value}"></Setter> </Style> <Style x:Key="AssetPresenterStyle" TargetType="{x:Type igDP:CellValuePresenter}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <ig:XamMultiColumnComboEditor ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.AssetClasses}" EmptyText="All" AllowDropDownResizing="True" AllowMultipleSelection="True" CheckBoxVisibility="Visible" SelectedItemsResetButtonVisibility="Visible" SelectionChanged="AssetClassesCombo_SelectionChanged" Background="Transparent" Foreground="White" BorderThickness="0" Loaded="XamMultiColumnComboEditor_Loaded"> <ig:XamMultiColumnComboEditor.Columns> <ig:TextComboColumn Key="Name" HeaderText="Asset Class"/> </ig:XamMultiColumnComboEditor.Columns> </ig:XamMultiColumnComboEditor> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style TargetType="{x:Type igDP:DataRecordPresenter}" > <EventSetter Event="Loaded" Handler="CashParameterGrid_DataRecordPresenter_Loaded"/> </Style> </ResourceDictionary> </igDP:XamDataGrid.Resources> <igDP:XamDataGrid.FieldSettings> <igDP:FieldSettings Width="*" LabelClickAction="Nothing"/> </igDP:XamDataGrid.FieldSettings> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AllowDelete="True" AllowAddNew="True" AddNewRecordLocation="OnTop" AllowFieldMoving="WithinLogicalRow" AutoGenerateFields="False" HighlightAlternateRecords="True" RecordSelectorStyle="{StaticResource AddRemoveStyle}" SelectionTypeCell="Extended" SelectionTypeRecord="Extended"/> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:FieldLayout.Fields> <igDP:Field Name="Parameter"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource ParameterScopeStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="Value"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource ComboEditor}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="CashDefinition" Label="Cash Definition"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource CashDefStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:UnboundField Name="AssetClasses" Label="Asset Classes"> <igDP:UnboundField.Settings> <igDP:FieldSettings CellValuePresenterStyle="{StaticResource AssetPresenterStyle}"/> </igDP:UnboundField.Settings> </igDP:UnboundField> <igDP:Field Name="UseMinCash" Label="Preserve Min Cash"/> </igDP:FieldLayout.Fields> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> </Grid> </igDock:ContentPane> </igDock:SplitPane> <igDock:ContentPane Header="Cash Holdings" igDock:SplitPane.RelativeSize="100,200" CloseButtonVisibility="Collapsed" WindowPositionMenuVisibility="Collapsed" AllowClose="False"> <igDP:XamDataGrid x:Name="CashValuesGrid" GroupByAreaLocation="None" DataSource="{Binding CashValues}" Grid.Row="1"> <igDP:XamDataGrid.FieldSettings> <igDP:FieldSettings AllowEdit="False" Width="*" AllowRecordFiltering="True" FilterLabelIconDropDownType="MultiSelectExcelStyle"/> </igDP:XamDataGrid.FieldSettings> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AllowDelete="False" AllowAddNew="False" AllowFieldMoving="WithinLogicalRow" AutoGenerateFields="False" HighlightAlternateRecords="True" FilterUIType="LabelIcons" RecordSelectorLocation="None" ExpansionIndicatorDisplayMode="CheckOnDisplay"/> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:FieldLayout.SortedFields> <igDP:FieldSortDescription Direction="Ascending" FieldName="ACCT_NO"/> </igDP:FieldLayout.SortedFields> <igDP:FieldLayout.Fields> <igDP:Field Name="LadderValues"/> <igDP:Field Name="ACCT_NO" Label="Account"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource PoolmanDecimalStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="PM_NAME" Label="PM"/> <igDP:Field Name="STRATEGY_IND" Label="Strategy"/> <igDP:Field Name="PURE_CASH" Label="Pure Cash"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="MV"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="LIQUIDITY_TARGET" Label="Liquidity Target"> <igDP:Field.Settings> <igDP:FieldSettings> <igDP:FieldSettings.EditorStyle> <Style TargetType="{x:Type igEditors:XamNumericEditor}"> <Setter Property="Format" Value="#0.##%"/> </Style> </igDP:FieldSettings.EditorStyle> </igDP:FieldSettings> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="MinCash" Label="Min Cash"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="SHORT_TBA_CASH" Label="Short TBA Cash"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="AvailableCash" Label="Spendable Cash"> <igDP:Field.Settings> <igDP:FieldSettings AllowEdit="True" EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> </igDP:FieldLayout.Fields> </igDP:FieldLayout> <igDP:FieldLayout Key="LadderValues"> <igDP:FieldLayout.Fields> <igDP:Field Name="DERIVED_TYPE" Label="Asset Class"/> <igDP:Field Name="MOD2A" Label="Mod2a"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="TRUE_CASH" Label="True Cash"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="MOD_TRUE_CASH" Label="Mod True Cash"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> <igDP:Field Name="LIQUID_ASSETS" Label="Liquid Assets"> <igDP:Field.Settings> <igDP:FieldSettings EditorStyle="{StaticResource USDAmountStyle}"/> </igDP:Field.Settings> </igDP:Field> </igDP:FieldLayout.Fields> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid>
Hello Sam,
You can access the Editor by using the following code in the foreach loop:
XamComboEditor xce = CellValuePresenter.FromCell(item).Editor;
Hope this helps you.
Thank you Stephen I think I am almost there....
Once I have a reference to the cell I need the object which points to the XamComboEditor. I need to call my method (ParameterScopeChanged) with that object as follows:
private void ParameterScopeChanged(object sender, RoutedEventArgs e) { XamComboEditor scopeCombo = ((XamComboEditor)sender);
How do I do that? Thanks for your help!!
Your Style could look like this:
<Style TargetType="{x:Type igDP:DataRecordPresenter}"> <EventSetter Event="Loaded" Handler="DRPLoaded"/> </Style>
And the handler like this:
private void DRPLoaded(object sender, RoutedEventArgs e) { if (!(sender as DataRecordPresenter).IsAddRecord && !(sender as DataRecordPresenter).IsFilterRecord) { foreach (var item in ((sender as DataRecordPresenter).Record as DataRecord).Cells) { //Here you can access the Cells of the currently loaded DataRecordPresenter. //Also this event will fire for every DataRecordPresenter } } }
Hello Stephen, I found a post that explains how to do what you describe but I dont see a property of the DataRecordPresenter that will allow me to iterate grid rows and cells (although I can access data as its native type).
Thanks
Thank you for your post. I have been looking into it and I suggest you create a Style for the DataRecordPresenter and handle its Loaded event and in it you can access the Cells and their values.