1

I have a method DateTime TimestampToDatetime(long Timestamp) (return new DateTime(Timestamp)) defined in MonkeyViewModel,

and a variable long DateModified which is a timestamp defined in Monkey Model.

In the XAML, I want the timestamp display as a datetime string, for example, the long DateModified 1685299649000 display as a string datetime May 28, 2023

How can I do something like TimestampToDatetime(DateModified).toString()?

In other words, is it possible to bind two properties into same tag and inside the same binding attribute and pass one of the properties to another as a parameter?

Is there any similar syntax like the following:

<Label Text="{
Binding TimestampToDatetime, x:Type ViewModel: MonkeyViewModel
    ({
        Binding DateModified, x:Type model:Mondey
    }).tostring()
}">
Julian
  • 5,290
  • 1
  • 17
  • 40
Cheng
  • 45
  • 5
  • 1
    first, you can only bind to **public properties**. You can use a [ValueConverter](https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/converters) to apply conversions and transformations to bound properties – Jason May 28 '23 at 19:04
  • see [this question](https://stackoverflow.com/questions/71595765/convert-timestamp-long-type-into-date-and-time-from-xaml-using-stringformat) for a similar converter (not for Xamarin, but the converter code should be nearly identical) – Jason May 28 '23 at 19:05
  • While it’s not quite what you are asking, one approach is to add a computed property to the model. `public string DateModifiedString => TimestampToDateModified(…).ToString();` Then bind to that property. – ToolmakerSteve May 28 '23 at 19:08

1 Answers1

2

Remark: Generally, it's recommended to store dates as DateTime objects and not as other data types. You should use what's already there.

If you cannot or do not want to change your variable type, then you need to at least turn it into a property. If the value is subject to change, it needs to be made observable by either manually implementing the INotifyPropertyChanged interface or by using the MVVM Community Toolkit's Source Generators:

[ObservableProperty]
private long dateModified;

This will auto-generate a public property with the name DateModified for you (mind the difference of the lower case and upper case letters of the symbol names) looking similar to this under the hood:

private long dateModified;
public long DateModified
{
    get => dateModified;
    set
    {
        if(dateModified.Equals(value) return;
        dateModified = value;
        OnPropertyChanged();
    }
}

You can find more information about Source Generators on my blog.

Then, you can implement a value converter that converts a long to a DateTime, e.g.:

public class LongToDateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is long ticks)
        {
            return new DateTime(ticks);
        }
        // Fallback value, could also be something else
        return DateTime.MinValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

Note: You may need to modify the converter code according to your needs. I've assumed that the long value stores ticks. If it stores milliseconds or anything else, you need to use an appropriate conversion method.

You can then use this converter in your XAML to convert the DateModified property to a DateTime object and then specify a string format in the binding expression:

<ContentPage.Resources>
    <ResourceDictionary>
        <converters:LongToDateTimeConverter x:Key="LongToDateConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

<VerticalStackLayout>
    <Label
        Text="{Binding DateModified, Converter={StaticResource LongToDateConverter}, StringFormat='{0:M}, {0:yyyy}'}"/>
</VerticalStackLayout>

You may need to experiment with the string format until you have what you need. There's an extensive list of standard date and time formats. If I'm not mistaken, StringFormat='{0:M}, {0:yyyy}'} should produce something like May 28, 2023.

There are several other ways to do this, e.g. you could also convert the property to a string property and bind to that or change the converter to produce a formatted string already. I suggest to use the above solution, however, because it provides more flexibility regarding the string format. It's easier to change in the XAML and you could even provide different formats per locale and you can use different formats for separate labels while binding to the same property.

Julian
  • 5,290
  • 1
  • 17
  • 40