Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

DataGrid StringFormat

Open freeproa opened this issue 2 years ago • 4 comments

<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

freeproa avatar Oct 19 '22 09:10 freeproa

String format is wrong. See https://docs.avaloniaui.net/docs/data-binding/bindings#binding-stringformat

timunie avatar Oct 19 '22 15:10 timunie

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

freeproa avatar Oct 19 '22 15:10 freeproa

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.

timunie avatar Oct 19 '22 18:10 timunie

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.

freeproa avatar Oct 19 '22 20:10 freeproa

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);
        }
    }
}

mgnslndh avatar Nov 16 '22 15:11 mgnslndh

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}'}"/>

giard-alexandre avatar Apr 18 '24 18:04 giard-alexandre

fyi: with Avalonia 11 this works for me as well: <TextBlock Text="{Binding Timestamp, StringFormat='hh:mm:ss.fff'}" />

Yinimi avatar Apr 29 '24 11:04 Yinimi

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" };
    }
}

timunie avatar Apr 29 '24 12:04 timunie