I have a WPF project with a Ribbon ComboBox showing a list of countries that I'm trying to filter depending upon a selected RadioButton option (All, Africa, Asia, Europe). I'm basing my code on COMBOBOX filtering in WPF with MVVM which uses a ComboBox to select a continent and show the filtered countries in a ListBox but I'm having trouble converting this to use RadioButtons.
- There's a problem with the XAML isChecked="..." lines which appear to cause an 'Input string was not in a correct format' error in the EnumBooleanConverter but if I change them to 'ConverterParameter=0' the app runs. I based this on How to bind RadioButtons to an enum?.
- The default list of countries is initially shown in the ComboBox but the default country isn't displayed, instead it's blank.
- Clicking on a RadioButton has no effect on the list.
Clearly I'm doing something wrong but I don't know what. Can you help?
XAML:
<ribbon:RibbonRadioButton x:Name="AllContinents"
GroupName="Continents"
IsChecked="{Binding Path=SelectedRadioGroup, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:mySettings+Continent.All}}"> <= Causes run error
</ribbon:RibbonRadioButton>
<ribbon:RibbonRadioButton x:Name="Africa"
GroupName="Continents"
IsChecked="{Binding Path=SelectedRadioGroup, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:mySettings+Continent.Africa}}"> <= Causes run error
</ribbon:RibbonRadioButton>
C# Code behind (DataContext):
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
public class MySettings : INotifyPropertyChanged
{
private ObservableCollection<Country> countries;
private ContinentViewModel selectedContinent;
public ListCollectionView CountryView { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ContinentViewModel> Continents { get; set; }
private static string selectedCountry = "Germany"; // Default country
public MySettings()
{
countries =
new ObservableCollection<Country>(
new[]
{
new Country() { Continent = Continent.Africa, DisplayName = "Algeria" },
new Country() { Continent = Continent.Africa, DisplayName = "Egypt" },
new Country() { Continent = Continent.Europe, DisplayName = "France" }
new Country() { Continent = Continent.Europe, DisplayName = "Germany" }
});
CountryView = new ListCollectionView(countries);
CountryView.Filter = o => selectedContinent == null || ((Country)o).Continent == selectedContinent.Model;
Continents = new ObservableCollection<ContinentViewModel>(Enum.GetValues(typeof(Continent)).Cast<Continent>().Select(c => new ContinentViewModel { Model = c}));
}
public ListCollectionView CountryView
{
get { return countryView; }
set
{
countryView = value;
}
}
public class Country
{
public string DisplayName { get; set; }
public Continent Continent { get; set; }
}
public enum Continent
{
All,
Africa,
Asia,
Europe,
America
}
public class ContinentViewModel
{
public Continent Model { get; set; }
public string DisplayName
{
get
{
return Enum.GetName(typeof(Continent), Model);
}
}
}
public ContinentViewModel SelectedContinent
{
get { return selectedContinent; }
set
{
selectedContinent = value;
OnContinentChanged();
this.OnPropertyChanged("SelectedContinent");
}
}
private void OnContinentChanged()
{
CountryView.Refresh();
}
public int SelectedRadioGroup
{
get { return selectedRadioGroup; }
set
{
selectedRadioGroup = value;
}
}
public string SelectedCountry
{
get { return selectedCountry; }
set
{
if (selectedCountry == value) return;
selectedCountry = value;
OnPropertyChanged(nameof(SelectedCountry));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class EnumBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int integer = (int)value;
return integer == int.Parse(parameter.ToString()) ? true : (object)false; <= Error:Input string was not in a correct format
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((bool)value) ? parameter : Binding.DoNothing;
}
}