Terry Anderson
Terry Anderson

Reputation: 157

WPF Format Binding not working

I want to be able to show a distance in both metric and imperial units.However changing the unit system through a ComboBox isn't changing the format of the label.

Some details:

1) The data context is working fine

2) I get "4.00 km" when I start the program but changing the Combobox's value has no effect.

3) ObservableObject has OnPropertyChanged() and it's also working fine everywhere except here.

WPF UI

<ComboBox ItemsSource="{Binding UnitSystems}" SelectedValue="{Binding Units}"/>
<Label Content="{Binding Distance}" ContentStringFormat="{Binding DistanceFormat}"/>

C# View Model

public class ViewModel : ObservableObject
{
    private double distance = 4;
    public double Distance
    {
        get
        {
            return distance;
        }
        set
        {
            distance = value;
            OnPropertyChanged("Distance");
        }
    }

    private UnitSystem units;

    public List<UnitSystem> UnitSystems
    {
        get
        {
            return new List<UnitSystem>((UnitSystem[])Enum.GetValues(typeof(UnitSystem)));
        }
    }

    public UnitSystem Units
    {
        get
        {
            return units;
        }
        set
        {
            units = value;
            OnPropertyChanged("Units");
            OnPropertyChanged("DistanceFormat");
            OnPropertyChanged("Distance");
        }
    }

    public string DistanceFormat
    {
        get
        {
            if (Units == UnitSystem.Metric)
                return "0.00 km";
            else
                return "0.00 mi";
        }
    }
}

public enum UnitSystem
{
    Metric,
    Imperial
}

Edit: The multibinding solution below has the same problem and it's not because of the format strings. Using f3 and f4, I start with "4.000" and it doesn't change to "4.0000".

    <ComboBox ItemsSource="{Binding UnitSystems}" SelectedValue="{Binding Units}"/>
    <Label>
        <Label.Content>
            <MultiBinding Converter="{StaticResource FormatConverter}">
                <Binding Path="Distance"/>
                <Binding Path="DistanceFormat"/>
            </MultiBinding>
        </Label.Content>
    </Label>

Edit 2 (SOLVED): The problem was that ObservableObject didn't implement INotifyPropertyChanged and surprisingly worked fine until this point.

Upvotes: 0

Views: 65

Answers (1)

Bind Units to SelectedItem instead of SelectedValue:

<ComboBox 
    ItemsSource="{Binding UnitSystems}"
    SelectedItem="{Binding Units}"
    />

SelectedValue is used when you use SelectedValuePath="SomePropertyName" to specify a property of the selected item that you care about. But enums have no properties, so just grab the item itself.

Here's my stand-in for ObservableObject:

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string prop = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}

Nothing clever. I create those with a snippet.

Upvotes: 1

Related Questions