Avalonia
Avalonia copied to clipboard
DataGrid StringFormat
<DataGrid.Columns> <DataGridTextColumn Header="Date" Binding="{Binding InvoiceDate, StringFormat='{}{0:yyyy-MM-dd}'}"/> </DataGrid.Columns> Works OK. I define in DataGrid: AutoGeneratingColumn="Generator" Generator code:
private void Generator ( object sender, DataGridAutoGeneratingColumnEventArgs e ) { if ( e.Column is DataGridBoundColumn col ) { Type type = ( sender as DataGrid ).Items.GetType ().GetGenericArguments ()[ 0 ]; string name = e.PropertyName; var attr = type.GetProperty (name).GetCustomAttribute<DbColumnAttribute> (); if ( attr == null ) e.Cancel = true; else { e.Column.Header = attr.Name; if ( attr.Format != null ) ( col.Binding as Binding ).StringFormat = attr.Format;// "yyyy-MM-dd"; } } } Don't work. Output display: yyyy-MM-dd
String format is wrong. See https://docs.avaloniaui.net/docs/data-binding/bindings#binding-stringformat
You misunderstood my question. I was saying that Binding StringFormat in XAML markup works fine. But in the code in the AutoGeneratingColumn event method, when I try to set via reflection for the DataGridAutoGeneratingColumnEventArgs property e.Column.Binding.StringFomat ="yyyy-MM-dd" it does not work. See the method code in the first post. In my example, the property itself is DateTime
I still think string format is wrong. But i cant test it atm. Could you try "{0:yyyy-mm-dd}"
?
On the other hand it may be risky to use reflection here. Probably you need to create a new binding instead. But again, I can't test it this week.
case: ( col.Binding as Binding ).StringFormat = "{0:yyyy-MM-dd}"; output: datetime without change i.e. 01.01.2009 0:00:00
case: ( col.Binding as Binding ).StringFormat = "yyyy-MM-dd"; output: that same string: "yyyy-mm-dd"
case: ( col.Binding as Binding ).StringFormat = "{}{0:yyyy-MM-dd}"; output: crash DataGrid.
From my testing it is not enough to just set the StringFormat but you also need to replace the converter:
if(e.PropertyType == typeof(decimal))
{
e.Column.MinWidth = 100;
e.Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
if(e.Column is DataGridTextColumn textColumn)
{
textColumn.CellStyleClasses.Add("dividend");
if(textColumn.Binding is BindingBase binding)
{
binding.Mode = BindingMode.OneWay;
binding.StringFormat = "{0:N2}";
binding.Converter = new StringFormatValueConverter(binding.StringFormat, null);
}
}
}
I still think string format is wrong. But i cant test it atm. Could you try
"{0:yyyy-mm-dd}"
?On the other hand it may be risky to use reflection here. Probably you need to create a new binding instead. But again, I can't test it this week.
FWIW, on Avalonia 11, this now seems to work with the only caveat being that you need to add {}
at the beginning in order to escape the required squiggly brackets.
IE:
"{}{0:yyyy-mm-dd}"
will work. Or, in a full example:
<TextBlock Text="{Binding Some.DateTime, StringFormat='{}{0:hh:mm:ss}'}"/>
fyi: with Avalonia 11 this works for me as well: <TextBlock Text="{Binding Timestamp, StringFormat='hh:mm:ss.fff'}" />
StringFormat can't be updated after the Binding was initiated, but making a new Binding works:
private void DataGrid_OnAutoGeneratingColumn(object? sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.Column is DataGridTextColumn col)
{
(col.Binding) = new Binding(e.PropertyName) { StringFormat = "yyyy-MM-dd" };
}
}