I have a XamDataGrid with table data giving a master detail relationship.
Fields: Name, Retention Time, Signals => detail
Fields: Integral, Volume, Concentration…
Now the field integral can have different units thus the header must vary accordingly. As the signals are loaded dynamically and even the user can specify his own type of signals, the header label needs to be created on the fly for each record differently.
How can this be done?
I recommend reviewing the following blog on how to use the FieldLayoutInitialized event to add fields dynamically.
Let me know if you have any questions.
this blog has nothing in common with my question.
I was asking for varying headers of child records. The field names are static the headers(Field.Labels) have to be dynamic.
Do you mean child fields in a hierarchy?
Yes, that is what I said even in my first post.
I also prefer to set the DataSource oft the DataPresenter than the DataContext.
In order to access child layout/fields you have to use line 80 and index into another sub layout and change the Label.
In my example I am also setting the DataSource property in Xaml. How and when do you want to bind your grid?
to illustrate better what I mean here the grid with the current layout:
The "Area" field needs to have a varying header label according to the signal.
I am currently setting the grid during an update process caused by some internal state changes:
/// Redisplay if calibrations changed
private void Update(object sender, EventArgs e)
RunsTable.DataSource = null;
RunsTable.DataSource = Project.CalculationRuns;
To update the labels of the "Area" field i am currently using a rather crude work arround:
/// Show/hide signal names depending on run and
/// Check if signal requires different area display and create new cloned layout accordingly
private void RunsTable_AssigningFieldLayoutToItemDirect(object sender, AssigningFieldLayoutToItemEventArgs e)
Run run = e.Item as Run;
if (run != null)
e.FieldLayout = RunsTable.FieldLayouts["MultipleSignals"];
e.FieldLayout = RunsTable.FieldLayouts["SingleSignal"];
Peak peak = e.Item as Peak;
if (peak != null)
FieldLayout defaultLayout = RunsTable.FieldLayouts["Peak"];
string areaUnit = "V s";
Trace trace = peak.ParentTrace;
if (string.IsNullOrEmpty(trace.AreaUnit) || trace.AreaUnit == areaUnit)
if (trace != null)
areaUnit = trace.AreaUnit;
FieldLayout existing = null;
foreach (FieldLayout fieldLayout in RunsTable.FieldLayouts)
if (fieldLayout.Key.ToString() == areaUnit)
existing = fieldLayout;
if (existing != null)
e.FieldLayout = existing;
FieldLayout layout = new FieldLayout();
layout.Key = areaUnit;
foreach (Field field in defaultLayout.Fields)
Field clonedField = null;
if (field is TextField) clonedField = new TextField();
if (field is NumericField) clonedField = new NumericField();
clonedField.Name = field.Name;
clonedField.Format = field.Format;
clonedField.Width = field.Width;
clonedField.LabelTextAlignment = field.LabelTextAlignment;
clonedField.HorizontalContentAlignment = field.HorizontalContentAlignment;
clonedField.AllowEdit = field.AllowEdit;
clonedField.AllowSorting = field.AllowSorting;
clonedField.Visibility = field.Visibility;
clonedField.ToolTip = field.ToolTip;
clonedField.Settings.LabelPresenterStyle = field.Settings.LabelPresenterStyle;
if (field.Name == "Area")
clonedField.Label = "Area\r[" + areaUnit + "]";
clonedField.Label = field.Label;
e.FieldLayout = layout;
e.Handled = true;
This approach looks for changes in the desired label and clones a new layout if no match found.
I think one can find a more elegant solution.
Here is a blog post on changing out the sub field headers.
great, this works exacly as expected!