简体   繁体   中英

C# ComboBox binding showing wrong selected item

I created combobox and textblock binded to same property of viewmodel

<ComboBox ItemsSource="{Binding LanguagesViewModel.Items}"
                  ItemTemplate="{StaticResource ComboBoxLanguageTemplate}"
                  SelectedItem="{Binding LanguagesViewModel.SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  IsSynchronizedWithCurrentItem="True"
                  />
<TextBlock Text="{Binding LanguagesViewModel.SelectedItem.Language}" />

Result of this is showing me wrong selecteditem in combobox (always the first one). Textblock has always right value. When I select diferent value in combobox, textblock is properly updated. If I remove

IsSynchronizedWithCurrentItem="True"

then combobox is showing "empty" value. SelectedItem of Language should have right object (by debuging).

LanguageViewModel consist obsertvablecollection of languagemodel. Language model has implemented overriding equals and gethascode (by resharper) and has one string attribute Language:

protected bool Equals(LanguageModel other)
{
    return string.Equals(_language, other._language);
}

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != this.GetType()) return false;
    return Equals((LanguageModel) obj);
}

public override int GetHashCode()
{
    return (_language != null ? _language.GetHashCode() : 0);
}

What to change that combobox is showing right item?

Actually, your problem is not clear at all....

You said

Result of this is showing me wrong selecteditem in combobox

But what do you do to say so ? You try setting the current item from your VM ?

Please post more of your code.

Here is a working sample of interraction between combobox, textblock and viewmodel

XAML

<Window x:Class="So42246496.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:So42246496"
    mc:Ignorable="d"
    d:DataContext="{d:DesignInstance {x:Type local:LanguageViewModel}}"

    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <DataTemplate x:Key="ComboBoxLanguageTemplate">
        <TextBlock Text="{Binding Language}"></TextBlock>
    </DataTemplate>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="47*"/>
        <RowDefinition Height="17*"/>
        <RowDefinition Height="17*"/>
    </Grid.RowDefinitions>

    <ComboBox ItemsSource="{Binding Items}"
              ItemTemplate="{StaticResource ComboBoxLanguageTemplate}"
              SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
               Margin="2"
              />
    <TextBlock Text="{Binding SelectedItem.Language}" Grid.Row="1" Margin="2" />
    <Button Grid.Row="2" Content="Next item" Margin="2" Click="ButtonBase_OnClick"></Button>
</Grid>

MainWindow code behind

public partial class MainWindow : Window
{
    private LanguageViewModel vm;

    public MainWindow()
    {
        vm = new LanguageViewModel();
        DataContext = vm;
        InitializeComponent();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        vm.NextItemFromViewModel();
    }
}

Viewmodel

public class LanguageViewModel : INotifyPropertyChanged
{
    private LanguageModel _selectedItem;
    public event PropertyChangedEventHandler PropertyChanged;

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

    private int currentIndex = 1;
    public LanguageViewModel()
    {
        Items = new ObservableCollection<LanguageModel>();
        Items.Add(new LanguageModel { Language = "fr-FR" });
        Items.Add(new LanguageModel { Language = "en-GB" });
        Items.Add(new LanguageModel { Language = "en-US" });
        Items.Add(new LanguageModel { Language = "de-DE" });
        Items.Add(new LanguageModel { Language = "es-ES" });
        SelectedItem = Items[currentIndex];
    }

    public ObservableCollection<LanguageModel> Items { get; set; }

    public LanguageModel SelectedItem
    {
        get { return _selectedItem; }
        set { _selectedItem = value; OnPropertyChanged(); }
    }

    public void NextItemFromViewModel()
    {
        SelectedItem = Items[++currentIndex];
    }
}

Language Model

public class LanguageModel : INotifyPropertyChanged
{
    private string _language;

    public string Language
    {
        get { return _language; }
        set
        {
            _language = value;
            OnPropertyChanged();
        }
    }

    protected bool Equals(LanguageModel other)
    {
        return string.Equals(Language, other.Language);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((LanguageModel)obj);
    }

    public override int GetHashCode()
    {
        return (Language != null ? Language.GetHashCode() : 0);
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM