I like to dynamically add and delete column to the xamdatadatagrid.
To illustrate I have 3 list.
FirstList, secondlist, mainlist.
First and second list is empty.
Mainlist have some values.
I want to add column for the main list for every item that are added in first and second list.
How can add those filed dynamically and handle the binding?
Here is my sample code
<Grid> <StackPanel> <igDP:XamDataGrid DataSource="{Binding FirstList}" GroupByAreaLocation="None" Margin="5"> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoFitMode="Always" AddNewRecordLocation="OnTopFixed" AllowAddNew="True" SupportDataErrorInfo="RecordsAndCells" DataErrorDisplayMode="Highlight" AutoGenerateFields="False" /> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:Field Name="Name"/> <igDP:Field Name="Value"></igDP:Field> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> <igDP:XamDataGrid DataSource="{Binding SecondList}" GroupByAreaLocation="None" Margin="5" RecordAdded="SecondList_OnRecordAdded"> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoFitMode="Always" AddNewRecordLocation="OnTopFixed" AllowAddNew="True" SupportDataErrorInfo="RecordsAndCells" DataErrorDisplayMode="Highlight" AutoGenerateFields="False" /> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:Field Name="Name"/> <igDP:CheckBoxField Name="Selected"></igDP:CheckBoxField> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> <igDP:XamDataGrid DataSource="{Binding Data}" FieldLayoutInitialized="XamDataGrid_FieldLayoutInitialized" GroupByAreaLocation="None"> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoGenerateFields="False" AutoFitMode="Always" AddNewRecordLocation="OnBottomFixed" AllowAddNew="True" SupportDataErrorInfo="RecordsAndCells" DataErrorDisplayMode="Highlight"/> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:Field Name="Name"/> <igDP:UnboundField BindingPath="Parameters[0].Value"/> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid> </StackPanel> </Grid>
public class MainViewModel { public MainViewModel() { Data = new ObservableCollection<MyViewModel>(); FirstList = new ObservableCollection<FirstClass>(); FirstList.CollectionChanged += FirstList_CollectionChanged; SecondList = new ObservableCollection<SecondClass>(); SecondList.CollectionChanged += SecondList_CollectionChanged; Random r = new Random(); int inner = r.Next(5, 15); for (int i = 0; i < 10; i++) { MyViewModel vm = new MyViewModel() { Name = "Name " + i, Parameters = new List<Parameter>() }; for (int j = 0; j < inner; j++) { vm.Parameters.Add(new Parameter { ParameterName = "Parameter " + j, Value = r.Next(10000).ToString() }); } Data.Add(vm); } } private void SecondList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //Add and delete dynamic column to the MyViewModel } private void FirstList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //Add and Delete dynamic column to the MyViewModel } public ObservableCollection<MyViewModel> Data { get; set; } public ObservableCollection<FirstClass> FirstList { get; set; } public ObservableCollection<SecondClass> SecondList { get; set; } } public class MyViewModel { public string Name { get; set; } public List<Parameter> Parameters { get; set; } } public class Parameter { public string ParameterName { get; set; } public string Value { get; set; } }
public class FirstClass : BaseNotifier { private string _name; private double _value; public String Name { get { return _name; } set { _name = value; OnPropertyChanged(nameof(Name)); } } public double Value { get { return _value; } set { _value = value; OnPropertyChanged(nameof(Value)); } } public FirstClass(string name, double value) { Name = name; Value = value; } } public class SecondClass : BaseNotifier { private string _name; private bool _selected; public String Name { get { return _name; } set { _name = value; OnPropertyChanged(nameof(Name)); } } public bool Selected { get { return _selected; } set { _selected = value; OnPropertyChanged(nameof(Selected)); } } public SecondClass(string name, bool selected) { Name = name; Selected = selected; } }
public partial class MainWindow : Window { MainViewModel vm; public MainWindow() { InitializeComponent(); vm = new MainViewModel(); DataContext = vm; } private void XamDataGrid_FieldLayoutInitialized(object sender, Infragistics.Windows.DataPresenter.Events.FieldLayoutInitializedEventArgs e) { MyViewModel elem = vm.Data.First(); for (int i = 0; i < elem.Parameters.Count; i++) { UnboundField field = new UnboundField { Name = elem.Parameters[i].ParameterName, BindingPath = new PropertyPath("Parameters[" + i + "].Value") }; e.FieldLayout.Fields.Add(field); } } private void SecondList_OnRecordAdded(object sender, RecordAddedEventArgs e) { //Initialize the new created item depending on current configuration of method/reflection var viewModel = DataContext as MainViewModel; if (viewModel != null) { viewModel.SecondList.Add(e.Record.DataItem as SecondClass); } } }
Hello,
I attached a sample below.
XamDataGridDynamicColumnsGroupBy.zip
<infragistic:XamDataGrid Grid.Row="1" DataSource="{Binding GeometryList }" PreviewKeyDown="DataGrid_PreviewKeyDown" Name="InputGeometryDataGrid" GroupByAreaLocation="None"> <infragistic:XamDataGrid.FieldLayoutSettings> <infragistic:FieldLayoutSettings AutoGenerateFields="False" AutoFitMode="Always" AddNewRecordLocation="OnTopFixed" AllowAddNew="True" SupportDataErrorInfo="RecordsAndCells" DataErrorDisplayMode="ErrorIconAndHighlight" AllowDelete="False" SelectionTypeRecord="Single"/> </infragistic:XamDataGrid.FieldLayoutSettings> <infragistic:XamDataGrid.Resources> <Style x:Key="{x:Type infragistic:DataRecordCellArea}" TargetType="{x:Type infragistic:DataRecordCellArea}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Record.DataItem.IsOk, UpdateSourceTrigger=PropertyChanged}" Value="false"> <Setter Property="BorderBrush" Value="#FFFFDC00"/> </DataTrigger> </Style.Triggers> </Style> </infragistic:XamDataGrid.Resources> <infragistic:XamDataGrid.FieldLayouts> <infragistic:FieldLayout> <infragistic:FieldLayout.Fields> <infragistic:Field Name="Name" Label="Name"></infragistic:Field> <infragistic:TemplateField Name="GuideModelData" Label="Guide model data" > <infragistic:TemplateField.EditTemplate> <DataTemplate> <controls:SearchableDropBox DomainObject="{igEdit:TemplateEditorValueBinding UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" InputValidationManifest="{Binding Path=DataContext.GuideModelDataValidation, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Mode=OneWay}" ToolTipHeader="Target guide model data " ToolTipText="Select a supported seismic type" ToolTipService.IsEnabled="True" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Validation.ErrorTemplate="{StaticResource CommonErrorTemplate}" Name="GuideModelData"/> </DataTemplate> </infragistic:TemplateField.EditTemplate> <infragistic:TemplateField.DisplayTemplate> <DataTemplate> <controls:PresentationBox Name="GuideModelData" DomainObject="{igEdit:TemplateEditorValueBinding UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" Validation.ErrorTemplate="{StaticResource CommonErrorTemplate}" ></controls:PresentationBox> </DataTemplate> </infragistic:TemplateField.DisplayTemplate> </infragistic:TemplateField>
Here is my sample for "normal case" (TemplateField Name="GuideModelData" Label="Guide model data" )
How can I add this kind of behavior to the table dynamically, as an unbound field?
Not really I sure I follow. Can you provide an example? But regardless it's not something that is exposed directly from the grid. So this is a bit out of scope.
Thank you, I sort it out.
Can I add my custom UI elements instead of unbound fields dynamically?
In normal cases, I create a template file and add my custom UI elements for edit and display template.
Can I add the same behavior to the unbound filed?
Thank you for contacting Infragistics. You will probably need to set the BindingType property on the Unbound fields as well to use AlternateBinding. Use link in the description for more details.
Creating dynamic unbound fields has been fully explained in this blog post by Brian Lagunas, our product manager.