1

I'm building a .NET MAUI app using the CommunityToolkit.Mvvm [ObservableProperty] attribute for data binding.

Example:

[ObservableProperty]
public decimal _count;

Setting the value:

decimal count = 2;
Item.Count = count;

If Count is a normal property, the UI shows 2 as expected.

But when using [ObservableProperty], the UI shows 2.000.

I need the number of decimal places to be fully dynamic:

  • If it's an integer value → show 2
  • If it's 2.5 → show 2.5
  • If it's 2.1234567890 → show exactly that (up to 10 decimals in my case)

I cannot hardcode a format like "0.##" because the number of decimal places changes depending on other data in the object.

Question: why is [ObservableProperty] changing the formatting in the UI, and how can I keep the property observable while showing a completely dynamic number of decimal places?

Notes:

  • Item is part of my view model.
  • I'm using .NET MAUI and CommunityToolkit.Mvvm.
  • Formatting should reflect the actual decimal value — no forced trailing zeros.
  • The formatting issue only happens with [ObservableProperty] or INotifyPropertyChanged

Edit:

Here is the Code for my UI:

<CollectionView Grid.Row="1"
                ItemsSource="{Binding Items}"
                SelectedItem="{Binding SelectedItem}"
                SelectionMode="Single"
                EmptyView="No Data"
                ItemSizingStrategy="MeasureFirstItem"
                x:Name="List">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout>
           
            <Grid ColumnDefinitions=".5*, .25*, .25*"
                      Padding="8,8,8,8"
                      RowSpacing="8" HeightRequest="40">
                <Label Text="{Binding Name}" Grid.Column="0" FontSize="12" VerticalOptions="Center" HorizontalOptions="Start"/>
                <Label Text="{Binding Name2}" Grid.Column="1" FontSize="12" VerticalOptions="Center" HorizontalOptions="End"/>
                <Label Text="{Binding Count}" Grid.Column="2" FontSize="12" VerticalOptions="Center" HorizontalOptions="End"/>
            </Grid>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>
4
  • Please show the UI-side code for both your cases (with and without ObservabelPropertyAttribute) Commented Aug 14 at 18:05
  • I added the code for the UI to the question. Commented Aug 14 at 21:49
  • Can I do this dynamically? If the property isn’t observable I can set the variable to 2 or 2.00 and it gets displayed the way I set it Commented Aug 14 at 22:32
  • 1
    Use the "G" format specifier; e.g. public string CountDisplay => $"{count:G}"; Commented Aug 15 at 2:43

2 Answers 2

0

It may be time to move away from the [ObservableProperty] and use the field contextual keyword. It is part of C#13 and can be used in preview. Edit your project file and set.

<LangVersion>preview</LangVersion>

C#14 will be out in a few months.

Below are some properties that I use that require a property change notification

public string? Image { get => field; set => Notify(ref field, value); }
public string? Description { get; set => Notify(ref field, value); }
public decimal? Amount { get; set => Notify(ref field, value); }

public event PropertyChangedEventHandler? PropertyChanged;
public void Notify<V>(ref V to, V from, [CallerMemberName] string property = "")
{
    if (property == null)
    {
        return;
    }

    if (to == null && from == null)
    {
        return;
    }

    if (to != null && to.Equals(from))
    {
        return;
    }

    to = from;
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

I reference the field contextual keyword in the get accessor of the Image property although a get accessor that does not specify a backing field will automatically return field.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/field

Sign up to request clarification or add additional context in comments.

Comments

0

Everything I tried didn't work until I did this. I expanded my Object cointaining Count with the Properties DecimalPlaces and CountDisplay. Then I did this:

[ObservableProperty]
public decimal _count;
public int DecimalPlaces => DecimalPlacesHelper.GetDecimalPlaces(this);
public string CountDisplay => Count.ToString($"F{DecimalPlaces }");

partial void OnCountChanged(decimal value)
{
    OnPropertyChanged(nameof(CountDisplay));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.