Reputation: 157
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
Reputation: 37060
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