【问题标题】:C# ComboBox binding showing wrong selected itemC# ComboBox 绑定显示错误的选定项
【发布时间】:2017-07-03 22:38:57
【问题描述】:

我创建了绑定到视图模型相同属性的组合框和文本块

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

结果显示组合框中的选择项错误(始终是第一个)。文本块始终具有正确的值。当我在组合框中选择不同的值时,文本块会正确更新。如果我删除

IsSynchronizedWithCurrentItem="True"

然后组合框显示“空”值。语言的 SelectedItem 应该有正确的对象(通过调试)。

LanguageViewModel 包含可观察的语言模型集合。语言模型已经实现了覆盖 equals 和 gethascode(通过 resharper)并且有一个字符串属性 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);
}

如何更改组合框显示正确的项目?

【问题讨论】:

  • 如何设置/获取 LanguagesViewModel.SelectedItem
  • LanguagesViewModel.SelectedItem = Show.LanguageLink; 设置不同节目时触发。
  • 问题是你设置选择项的方式错误,你需要将选择项设置为LanguagesViewModel.Items列表之一。这就是为什么您的 ComboBox 无法正确显示它的原因,ComboBox 中没有此类项目并且无法选择它。
  • 哦,这很好。谢谢

标签: c# wpf data-binding combobox


【解决方案1】:

其实你的问题一点都不清楚....

你说

结果显示我在组合框中选择了错误的项目

但是你怎么这么说呢?您尝试从您的 VM 设置当前项目?

请发布更多您的代码。

这是组合框、文本块和视图模型之间交互的工作示例

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 后面的代码

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

视图模型

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

语言模型

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

【讨论】:

  • 问题是所选项目的设置,正如 Shakra 在原帖下的 cmets 中指出的那样。我只是没有将其设置为 Items 项。
猜你喜欢
  • 2015-03-28
  • 2016-03-12
  • 2020-10-10
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2016-02-22
  • 2021-03-11
  • 2022-01-03
相关资源
最近更新 更多