Click here to Skip to main content
15,867,756 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
A have two combobox 1 combobox controls the list of the 2nd combobox. when i do my initial selection in the 1st combobox the 2nd combobox gets filter. but when i do a second selection on my 1st combobox i get the error - "Value '' could not be converted"

XAML
<ComboBox Margin="5 0 0 0" materialDesign:HintAssist.Hint="Municipal" Width="130" ItemsSource="{Binding MunicipalList}"  DisplayMemberPath="MUNICIPALNAME" SelectedValuePath="MUNICIPALID"  SelectedValue="{Binding MunicipalParam, TargetNullValue = '', Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>


What I have tried:

could not identify why its generating the error.
Posted
Updated 6-Mar-23 13:35pm
Comments
Graeme_Grant 6-Mar-23 0:32am    
Not enough information.

Here is an example from another question asking for a similar solution:

1. MainWindow.xaml.
C#
public partial class MainWindow : INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        _ = LoadData();
    }

    // data source: https://datahub.io/core/world-cities#data
    private string _url = "https://pkgstore.datahub.io/core/world-cities/world-cities_json/data/5b3dd46ad10990bca47b04b4739a02ba/world-cities_json.json";

    private CountryDTO? selectedCountry;
    private ListCollectionView? filteredCountriesView;
    private ListCollectionView? filteredCitiesView;

    public List<CountryDTO> Countries { get; } = new();

    public ListCollectionView? FilteredCountriesView
    {
        get => filteredCountriesView;
        private set
        {
            if (Equals(value, filteredCountriesView)) return;

            filteredCountriesView = value;
            OnPropertyChanged();
        }
    }

    public ListCollectionView? FilteredCitiesView
    {
        get => filteredCitiesView;
        private set
        {
            if (Equals(value, filteredCitiesView)) return;

            filteredCitiesView = value;
            OnPropertyChanged();
        }
    }

    public CountryDTO? SelectedCountry
    {
        get => selectedCountry;
        set
        {
            if (Equals(value, selectedCountry)) return;

            selectedCountry = value;

            ApplyCityFilter();
            OnPropertyChanged();
        }
    }

    private async Task LoadData()
    {
        JsonSerializerOptions options = new();

        await using Stream stream = await new HttpClient().GetStreamAsync(_url);

        // deserialize the stream an object at a time...
        await foreach (CountryDTO item in JsonSerializer
                           .DeserializeAsyncEnumerable<CountryDTO>(stream, options))
        {
            Countries.Add(item);
        }

        PrepareCountryFiltering();
        PrepareCityFiltering();

        ApplyCountryFilter();
        SelectedCountry = Countries.First();
    }

    private void PrepareCountryFiltering()
    {
        FilteredCountriesView = (ListCollectionView)
            new CollectionViewSource { Source = Countries }.View;

        FilteredCountriesView.SortDescriptions.Clear();
        FilteredCountriesView.SortDescriptions.Add(
            new SortDescription(nameof(CountryDTO.CountryName),
            ListSortDirection.Ascending));
    }

    private void PrepareCityFiltering()
    {
        FilteredCitiesView = (ListCollectionView)
            new CollectionViewSource { Source = Countries }.View;

        FilteredCitiesView.SortDescriptions.Clear();
        FilteredCitiesView.SortDescriptions.Add(
            new SortDescription(nameof(CountryDTO.CityName),
            ListSortDirection.Ascending));
    }

    // Filter
    public bool DistinctCountry(object item)
    {
        CountryDTO? model = item as CountryDTO;
        if (model is null) return false;

        int index1 = Countries.IndexOf(model);
        int index2 = Countries.IndexOf(Countries.Last(x => 
            (x.CountryName ?? "no country name").Equals(model.CountryName)));

        return index1 == index2;
    }

    public bool FilterByCountry(object item)
    {
        CountryDTO? dto = item as CountryDTO;
        return (dto?.CountryName ?? "no country name")
            .Equals(SelectedCountry?.CountryName ?? "not selected");
    }

    private void ApplyCountryFilter()
    {
        if (FilteredCountriesView is null) return;
        FilteredCountriesView.Filter = DistinctCountry;
    }
    private void ApplyCityFilter()
    {
        if (FilteredCitiesView is null) return;
        FilteredCitiesView.Filter = FilterByCountry;
    }

    public event PropertyChangedEventHandler? PropertyChanged;

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

public class CountryDTO
{
    [JsonPropertyName("country")]
    public string? CountryName { get; set; }

    [JsonPropertyName("name")]
    public string? CityName { get; set; }
}

2. MainWindow.xaml
XML
<Window x:Class="WpfCascadingComboBoxes.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfCascadingComboBoxes"
        x:Name="Window"
        mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
    <Grid DataContext="{Binding ElementName=Window}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <ComboBox Grid.Column="0"
                  Width="200"
                  VerticalAlignment="Center"
                  DisplayMemberPath="CountryName"
                  ItemsSource="{Binding FilteredCountriesView}"
                  SelectedItem="{Binding SelectedCountry}"/>

        <ComboBox Grid.Column="1"
                  Width="200"
                  VerticalAlignment="Center"
                  DisplayMemberPath="CityName"
                  ItemsSource="{Binding FilteredCitiesView}"/>
    </Grid>
</Window>

The solution will download a list of countries and cities. The First ComboBox has the Contries, then the second with dynamically show the cities based on the country selected.
 
Share this answer
 
Start with the documentation: Binding.TargetNullValue Property (Windows.UI.Xaml.Data) - Windows UWP applications | Microsoft Learn[^] - either omit the TargetNullValue completely, or provide it with a sensible value.
 
Share this answer
 
Comments
Graeme_Grant 6-Mar-23 0:54am    
It is more involved. There is no context if that is the first or second list, nor how the second list is filtered.
OriginalGriff 6-Mar-23 1:21am    
Almost certainly - but that's what is causing the error message. :D
joey sison 6-Mar-23 17:16pm    
Hello the one showing the error is Combobox2
combobox1 Province XAML -
<combobox materialdesign:hintassist.hint="Province" style="{StaticResource MaterialDesignFloatingHintComboBox}" width="130" itemssource="{Binding ProvinceList}" displaymemberpath="PROVINCENAME" selectedvaluepath="PROVINCEID" selectedvalue="{Binding ProvinceParam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

Combobox2 Municipality XAML
<combobox margin="5 0 0 0" materialdesign:hintassist.hint="Municipal" style="{StaticResource MaterialDesignFloatingHintComboBox}" width="130" itemssource="{Binding MunicipalList}" displaymemberpath="MUNICIPALNAME" selectedvaluepath="MUNICIPALID" selectedvalue="{Binding MunicipalParam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">


Combobox1 Coding
int _ProvinceParam = -1;
public int ProvinceParam
{
get { return _ProvinceParam; }
set
{
_ProvinceParam = value;
NotifyOfPropertyChange(() => ProvinceParam);
if (_ProvinceParam > -1)
{

_MunicipalList = new BindableCollection<municipalitymodel>(_dbConnection.GetMunicipalList(" where PROVINCEID ='" + _ProvinceParam + "' Order by MUNICIPALNAME"));
NotifyOfPropertyChange(() => MunicipalList);

}

}
}

The idea is that whatever is selected in the combobox1-Province filters the selection in the Combobox2-municipality. i tried removing the TargetNullValue but still the error shows in combobox2-Municipality.
Graeme_Grant 6-Mar-23 18:01pm    
See Solution 2 which will do what you want with similar data.
I tried the solution presented it works good, though it uses ListView. but i was able to figure the solution through it.

as combobox1 recreates the new data in combobox2, and SelectedValue in Combobox2 is reset and contains null value causing the error.

all i did was before recreating the combobox2 value i just assigned the SelectedValue to "-1". thus the solution. FilteredCitiesView.SortDescriptions.Clear(); - got the idea from this... :D :D :D

thanks so much - Graeme_Grant
 
Share this answer
 
Comments
Graeme_Grant 7-Mar-23 5:11am    
You are welcome 😊

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900