Different number of decimals each grid row
Hi,
is it possible to format (display and editing) a GridNumericColumn with dynamic number of decimals?
Imagine you have a SfDataGrid with at least two columns. A integer column "NumberOfDecimals" and and a double column "Value".
The NumberOfDecimals-column contains only "0" or "2" and the grid should display the Value-column with format depending on the NumberOfDecimals-column.
Value-cell editing should also allow only 2 or 0 decimals.
Do I need a MultiBinding converter?
Regards
Harald
SIGN IN To post a reply.
9 Replies
FP
Farjana Parveen Ayubb
Syncfusion Team
January 17, 2017 09:07 AM UTC
Hi Harald,
Thank you for contacting Syncfusion Support.
We have analyzed your query, you can achieve your requirement by using DisplayBinding in GridColumn for display the value, and you have to customize the GridCellNumericRenderer and override the OnInitalizedEditElement method for editing the value.
Please refer the below code example and sample in the following location,
Code Example:
GridColumn
|
<syncfusion:SfDataGrid ItemsSource="{Binding Path=ValueList}" AllowEditing="True" x:Name="sfdatagrid">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridNumericColumn MappingName="NumberOfDecimals" />
<syncfusion:GridNumericColumn MappingName="Value"
DisplayBinding="{Binding Converter={StaticResource decimalDigitConverter}}"/>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid> |
Converter
|
public class DecimalDigitConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && (value as Model) != null)
{
int decimalDegits = (value as Model).NumberOfDecimals;
if (decimalDegits == 0)
return Math.Floor((value as Model).Value);
else
return Math.Round((value as Model).Value,2);
}
return null;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
} |
CustomGridCellNumericRenderer
|
public class GridNumericColumnRendererExt : GridCellNumericRenderer
{
public override void OnInitializeEditElement(DataColumnBase dataColumn, DoubleTextBox uiElement, object dataContext)
{
if (dataColumn.GridColumn.MappingName == "Value")
{
int decimalDegits = (dataContext as Model).NumberOfDecimals;
if (decimalDegits == 0)
{
uiElement.Value = Math.Floor((dataContext as Model).Value);
uiElement.NumberDecimalDigits = 0;
}
else
{
uiElement.Value = Math.Round((dataContext as Model).Value, 2);
uiElement.NumberDecimalDigits = 2;
}
var column = dataColumn.GridColumn;
var textPadding = new Binding { Path = new PropertyPath("Padding"), Mode = BindingMode.OneWay, Source = column };
uiElement.SetBinding(Control.PaddingProperty, textPadding);
var textAlignBind = new Binding { Path = new PropertyPath("TextAlignment"), Mode = BindingMode.TwoWay, Source = column };
uiElement.SetBinding(TextBox.TextAlignmentProperty, textAlignBind);
var textWrappingBinding = new Binding { Path = new PropertyPath("TextWrapping"), Mode = BindingMode.TwoWay, Source = column };
uiElement.SetBinding(TextBox.TextWrappingProperty, textWrappingBinding);
var verticalContentAlignment = new Binding { Path = new PropertyPath("VerticalAlignment"), Mode = BindingMode.TwoWay, Source = column };
uiElement.SetBinding(Control.VerticalContentAlignmentProperty, verticalContentAlignment);
var textDecorations = new Binding { Path = new PropertyPath("TextDecorations"), Mode = BindingMode.TwoWay, Source = column };
uiElement.SetBinding(TextBox.TextDecorationsProperty, textDecorations);
}
}
} |
Sample Location: DisplayBinding_Sample
Regards,
Farjana Parveen A
HB
Harald Betzler
January 20, 2017 12:49 PM UTC
Hi Farjana,
thank you. That's what I need.
But after editing cells the new content is replaced by the old content.
Regards
Harald
GT
Gnanasownthari Thirugnanam
Syncfusion Team
January 23, 2017 08:37 AM UTC
Hi Harald,
We have analyzed your query, you can achieve your requirement “Commit the new value in cell after editing”, by invoking the base method in OnInitializeEditElement method like below code.
C#
|
public override void OnInitializeEditElement(DataColumnBase dataColumn, DoubleTextBox uiElement, object dataContext)
{
base.OnInitializeEditElement(dataColumn, uiElement, dataContext);
if (dataColumn.GridColumn.MappingName == "Value")
{
int decimalDegits = (dataContext as Model).NumberOfDecimals;
if (decimalDegits == 0)
{
uiElement.Value = Math.Floor((dataContext as Model).Value);
uiElement.NumberDecimalDigits = 0;
}
else
{
uiElement.Value = Math.Round((dataContext as Model).Value, 2);
uiElement.NumberDecimalDigits = 2;
}
}
} |
We have modified the sample as per your requirement, you can download the same from below mentioned location.
Sample location:
Regards,
Gnanasownthari T.
HB
Harald Betzler
January 23, 2017 07:58 PM UTC
Now it is perfect. Thank you.
GT
Gnanasownthari Thirugnanam
Syncfusion Team
January 24, 2017 10:06 AM UTC
Hi Harald,
Thanks for your update.
Please let me know if you have any further assistance on this.
Regards,
Gnanasownthari T.
HB
Harald Betzler
January 24, 2017 10:06 PM UTC
Hi Gnanasownthari,
please check my attached simple sample application.
There you can see my problem:
- I've an ItemType column and all records are assigned ItemType "A" or "B".
- My ViewModel adds a summary row for each ItemType with a calculated sum of the Value column.
- After editing a regular cells Value, an ItemChangedEvent recalculates the sum of the Value column for the specific ItemType and inserts the sum in the summary row.
- Although the sum is correctly saved in the ItemSource the displayed sum won't be updated - WHEN A DISPLAYBINDING CONVERTER IS USED
As you can see in my attached sample, it works if display binding converter is disabled, and it doesn't work if display binding is active.
Please help
Regards
Harald
Attachment: DisplayBinding_Sample_3cae0041.zip
SR
Sivakumar R
Syncfusion Team
January 24, 2017 10:48 PM UTC
Hi Harald,
Your requirement can be achieved using MultiBinding. Please find the sample and code snippet below,
XAML code
|
<syncfusion:GridNumericColumn MappingName="Value">
<syncfusion:GridNumericColumn.DisplayBinding>
<MultiBinding Converter="{StaticResource DecimalDigitConverter}">
<Binding Path="Value"/>
<Binding Path="NumberOfDecimals"/>
</MultiBinding>
</syncfusion:GridNumericColumn.DisplayBinding>
</syncfusion:GridNumericColumn> |
Multi Value Converter
|
public class DecimalDigitConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] == DependencyProperty.UnsetValue)
return 0;
if (values[1] == DependencyProperty.UnsetValue)
return 0;
var decimalDegits = (int)values[1];
var value = (double)values[0];
var val = decimalDegits == 0 ? Math.Floor(value) : Math.Round(value, decimalDegits);
return val.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
} |
Sample:
Thanks,
Sivakumar
HB
Harald Betzler
January 25, 2017 11:07 AM UTC
Hi Sivakumar,
thank you. Now it really works as expected.
it would be really perfect, if the requirement from query 1 of issue #171269 will be resolved (starting editing with a "inserted" minus sign).
Regards
Harald
JG
Jai Ganesh S
Syncfusion Team
January 25, 2017 06:25 PM UTC
Hi Harald,
Regarding query 1 for the incident # 171269, we have updated the response in that incident. Could you please follow up that incident for further follow ups?
Regards,
Jai Ganesh S
SIGN IN To post a reply.
- 9 Replies
- 5 Participants
-
HB Harald Betzler
- Jan 16, 2017 04:11 AM UTC
- Jan 25, 2017 06:25 PM UTC