2017-02-15 3 views
1

I erstellt Combobox und Textblock auf gleiche Eigenschaft von Viewmodel bindedC# ComboBox Bindung zeigt falsch ausgewählte Element

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

Ergebnis dieses mich nicht falsch SelectedItem in Combobox zeigt (immer der erste). Textblock hat immer den richtigen Wert. Wenn ich einen anderen Wert in der Combobox anwähle, wird der Textblock korrekt aktualisiert. Wenn ich entfernen

IsSynchronizedWithCurrentItem = "True"

dann Combobox zeigt "leeren" Wert. SelectedItem of Language sollte das richtige Objekt haben (durch Debuggen).

LanguageViewModel bestehen observablecollection des languagemodel. Sprachmodell hat überwiegendes gleich und gethascode (von ReSharper) implementiert und hat sich zu einem String-Attribut Sprache:

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); 
} 

Was das Combobox ändern richtigen Artikel zeigt?

+0

Wie stellen Sie/_LanguagesViewModel.SelectedItem_ bekommen? – Ron

+0

'LanguagesViewModel.SelectedItem = Show.LanguageLink;' Wird ausgelöst, wenn eine andere Show eingestellt wird. – Crooker

+1

Probleme sind, dass Sie das ausgewählte Objekt falsch setzen, Sie müssen das ausgewählte Element als eine der 'LanguagesViewModel.Items'-Liste festlegen. Deshalb können Sie ComboBox nicht korrekt anzeigen, es gibt kein solches Element in ComboBox und es kann es nicht auswählen. – Shakra

Antwort

0

Eigentlich ist Ihr Problem nicht klar, alle ....

sagte Sie

Daraus ergibt sich, mich nicht falsch SelectedItem in Combobox zeigt

Aber was tun Sie, das sagen? Sie versuchen, den aktuellen Artikel von Ihrer VM aus zu setzen?

Bitte poste mehr von deinem Code.

Hier ist eine Arbeitsprobe interraction zwischen Combobox, TextBlock- und Ansichtsmodell

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 hinter

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(); 
    } 
} 

Ansichtsmodell

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]; 
    } 
} 

Sprache Modell

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)); 
    } 
} 
+0

Problem war die Einstellung des ausgewählten Elements, wie von Shakra in Kommentaren unter Original Post hervorgehoben. Ich habe es einfach nicht als Items gesetzt. – Crooker

Verwandte Themen