Not able to select dropdown value

时间:2017-06-15 09:28:31

标签: c# wpf mvvm combobox

I have a combobox. It holds the category instance as selectedItem but when user dont found any suitable category in the dropdown option he can select create new and one one textbox appears down the combobox and user can enter the name of new category now user alters the dropdown and then user is not able to change the selection of category dropdown. Why is behaving strage?

Here is my code: MainWindow.xaml

 <StackPanel>
    <TextBlock Text="{Binding Name, Mode=TwoWay}"></TextBlock>
    <ComboBox x:Name="Category" ItemsSource="{Binding Categories}" DisplayMemberPath="Name" 
              SelectedItem="{Binding Menu.Category, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/>
    <TextBox Text="{Binding Menu.Category.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}">
        <TextBox.Style>
            <Style>
                <Setter Property="TextBox.Visibility" Value="Collapsed"></Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=Category, Path=SelectedItem.Id}" Value="-1">
                        <Setter Property="TextBox.Visibility" Value="Visible"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
 </StackPanel>

MainViewModel.cs

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {

        Name = "Jenish";
        Categories = new ObservableCollection<Category>();
        Categories.Add(new Category(){ Id = -1, Name = "Create New"});
        Categories.Add(new Category() { Id = 1, Name = "Test1" });
        Categories.Add(new Category() { Id = 2, Name = "Test2" });
        Menu = new Menu();
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged(() => Name);
        }
    }

    private ObservableCollection<Category> _categories;
    public ObservableCollection<Category> Categories
    {
        get { return _categories; }
        set
        {
            _categories = value;
            RaisePropertyChanged(() => Categories);
        }
    }

    private Menu _menu;
    public Menu Menu
    {
        get { return _menu; }
        set
        {
            _menu = value;
            RaisePropertyChanged(() => Menu);
        }
    }
}

Menu.cs

public class Menu : ViewModelBase
{
    private int _id;
    public int Id
    {
        get => _id;
        set
        {
            _id = value;
            RaisePropertyChanged(() => Id);
        }
    }

    private Category _category;

    public Category Category
    {
        get => _category;
        set
        {
            _category = value;
            RaisePropertyChanged(() => Category);
        }
    }
}

Category.cs

public class Category : ViewModelBase
{
    private int _Id;
    public int Id
    {
        get => _Id;
        set
        {
            _Id = value;
            RaisePropertyChanged(() => Id);
        }
    }

    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            RaisePropertyChanged(() => Name);
        }
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode() & Name.GetHashCode();//for reference type binding to the selectedItem in the combobox
    }
}

This issue only happens if user has selected Create New in the category and has altered the textbox text. If the user puts the text back as Create New again in the textbox then user can again change the selection of combobox.

Refer below image where I am not able to change the selection. enter image description here

1 个答案:

答案 0 :(得分:0)

After a long time of research and debugging I came to know that when user changes the selection of combobox. Framework calls Equals and GetHashCode on the object that is bind to the SelectedItem Property.

Bad thing about this code is that we should override the GetHashCode method very carefully and that method should not depend on the mutable properties or fields. So I changed implementation of GetHashCode like below and it worked... :)

public override int GetHashCode()
{
    return Id.GetHashCode();
}

Id will remain same and wont change so I removed the Name property's HashCode form the method and it just returns the Id.GetHashCode.