组合框的 WPF SelectedValue 未从 viewmodel 属性更新

托马斯五世

我的 MainWindow 中有以下组合框:

<ComboBox SelectedValue="{Binding LanguageId}" SelectedValuePath="Id" DisplayMemberPath="Name" ItemsSource="{Binding Languages}"/>

在我的 ViewModel 中,我设置了以下两个属性:

public List<Language> Languages
{
  get
  {
    return new List<Language>()
    {
     new Language { Id = 0, Name = ml.ml_string(100, "Language1") },
     new Language { Id = 1, Name = ml.ml_string(101, "Language2") },
     new Language { Id = 2, Name = ml.ml_string(102, "Language3") },
     new Language { Id = 3, Name = ml.ml_string(103, "Language4") }
    };
  }
}

public int LanguageId
{
  get
  {
    return _languageId;
  }
  set
  {
    _languageId = value;
    NotifyPropertyChanged("Languages");
    NotifyPropertyChanged();
  }
}

所以我想要的是在我在组合框中选择一种语言后通知我的 Languages 属性,但目前当我这样做时,它根本没有显示任何值(见图):组合框错误我该如何解决这个问题?

15ee8f99-57ff-4f92-890c-b56153

必须将所选项目视为等于集合中的项目。However, you always return a collection of new objects from Languages, so when the selection changes, you set ComboBox.ItemsSourceto a new collection which does not contain the object that was just selected. 因此ComboBox将所选项目值丢弃为无效。SelectedValuePath正如您发现的那样,使用无法解决此问题。

你可以通过重写解决这一问题Equals(Language)Language保持你的,或(更好)Languages围绕永久和重用他们。

如果您需要翻译该Name属性,您可以使用 value converter 来完成

我建议不要覆盖的原因Equals()是,在 C# 中,您习惯于假设比较引用类型的两个实例意味着Object.ReferenceEquals(),而打破该假设可能会导致错误。我根据经验说话。

由于我们不再使用该Name属性,我们可以更改Languages为一个List<int>Language Ids —— 在这种情况下,我们可以将其设为只读,而不必费心重新创建列表。我在这里做过。

public class LanguageNameConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0] is int)
        {
            var itemLanguageId = (int)values[0];
            var displayLanguageId = (int)values[1];

            //  Do stuff here to get the translated name of the item language
            var itemLanguageNameTranslated = $"Name of language {itemLanguageId} in language {displayLanguageId}";

            return itemLanguageNameTranslated;
        }
        else return values[0]?.GetType();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

<ComboBox 
    SelectedValue="{Binding LanguageId}" 
    ItemsSource="{Binding Languages}"
    >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Label>
                <Label.Content>
                    <MultiBinding 
                        Converter="{StaticResource LanguageNameConverter}"
                        >
                        <Binding Path="." />
                        <Binding 
                            Path="DataContext.LanguageId" 
                            RelativeSource="{RelativeSource AncestorType=ComboBox}" 
                            />
                    </MultiBinding>
                </Label.Content>
            </Label>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

如果您希望将Language保留在Languages,只需SelectedValuePath="Id"在 ComboBox 上恢复,并将Path第一个Binding中的 设置MultiBindingId而不是.

<ComboBox 
    SelectedValue="{Binding LanguageId}" 
    SelectedValuePath="Id"
    ...

...

<MultiBinding 
    Converter="{StaticResource LanguageNameConverter}"
    >
    <Binding Path="Id" />
    <Binding 
        Path="DataContext.LanguageId" 
        RelativeSource="{RelativeSource AncestorType=ComboBox}" 
        />
</MultiBinding>

等于覆盖解决方案

这是Equals()解决方案;我们尝试了它,但在选择更改后保留旧的 SelectedItem 时出现问题,其旧名称为先前选择的语言。那是因为Equals()覆盖的事情。所以我们选择了多值转换器,它不需要任何变通方法或有趣的业务。

按照 WPF 想要的方式做事,没有人会受到伤害。这就是规则。

public class Language
{
    public int Id { get; set; }
    public String Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Language)
        {
            return ((Language)obj).Id == Id;
        }
        return base.Equals(obj);
    }

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

如果您选择此解决方案,您还需要为您的LanuageId属性添加一个递归保护

private int _languageId;
public int LanguageId
{
    get
    {
        return _languageId;
    }
    set
    {
        if (_languageId != value)
        {
            _languageId = value;
            OnPropertyChanged("Languages");
            OnPropertyChanged();
        }
    }
}

替换ComboBox.ItemsSource现在将导致实际SelectedItem更改为一个新的对象实例,即 update SelectedValue,这将导致LanguageId再次设置——与它已经拥有的值相同。如果省略了递归后卫,LanguageIdset块将提高PropertyChangedLanguages再次将更新SelectedItem,等等-我们是去比赛,直到堆栈溢出。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

WPF数据绑定:视图未从viewmodel更新

来自分类Dev

文本框未从ViewModel更新其值

来自分类Dev

多绑定wpf组合框的SelectedValuePath和SelectedValue

来自分类Dev

WPF:我可以绑定到组合框的SelectedValue吗?

来自分类Dev

从WPF中的ViewModel更新时,组合框的SelectedItem值将为空

来自分类Dev

Silverlight组合框selectedValue字符串属性绑定

来自分类Dev

组合框SelectedItem在WPF中未更新

来自分类Dev

WPF可编辑组合框在键入时不会更改SelectedValue

来自分类Dev

WPF为页面组合框上的ComboBox设置SelectedValue

来自分类Dev

ViewModel 未从 ActivateItem() 激活

来自分类Dev

无法获取组合框的selectedValue,返回空

来自分类Dev

无法获取组合框的selectedvalue,返回空

来自分类Dev

Java组合框未从SQL填充

来自分类Dev

使用ReactiveUI WPF无法将Enum值列表从ViewModel绑定到视图中的组合框

来自分类Dev

WPF组合框样式不具有绑定属性

来自分类Dev

带字符串Bind to Int属性的WPF组合框

来自分类Dev

将 WPF 组合框绑定到用户设置属性

来自分类Dev

更改集合时,WPF组合框未更新

来自分类Dev

WPF DataGridTemplateColumn组合框更新所有行

来自分类Dev

WPF 组合框 SelectedItem 绑定不会从代码更新

来自分类Dev

WPF组合框问题

来自分类Dev

WPF组合框值

来自分类Dev

由于大小写不同,WPF组合框在ItemSource中找不到SelectedValue

来自分类Dev

从 ViewModel 属性绑定 WPF 中的 ImageAwesome 对象

来自分类Dev

WPF DataGridCheckBoxColumn的状态不会从ViewModel更新

来自分类Dev

如何将组合框的selectedValue转换为整数?

来自分类Dev

组合框的SelectedValue返回一个意外值

来自分类Dev

vb.net组合框selectedvalue事件错误

来自分类Dev

包含组合框的ItemTemplate-如何绑定到SelectedValue?

Related 相关文章

  1. 1

    WPF数据绑定:视图未从viewmodel更新

  2. 2

    文本框未从ViewModel更新其值

  3. 3

    多绑定wpf组合框的SelectedValuePath和SelectedValue

  4. 4

    WPF:我可以绑定到组合框的SelectedValue吗?

  5. 5

    从WPF中的ViewModel更新时,组合框的SelectedItem值将为空

  6. 6

    Silverlight组合框selectedValue字符串属性绑定

  7. 7

    组合框SelectedItem在WPF中未更新

  8. 8

    WPF可编辑组合框在键入时不会更改SelectedValue

  9. 9

    WPF为页面组合框上的ComboBox设置SelectedValue

  10. 10

    ViewModel 未从 ActivateItem() 激活

  11. 11

    无法获取组合框的selectedValue,返回空

  12. 12

    无法获取组合框的selectedvalue,返回空

  13. 13

    Java组合框未从SQL填充

  14. 14

    使用ReactiveUI WPF无法将Enum值列表从ViewModel绑定到视图中的组合框

  15. 15

    WPF组合框样式不具有绑定属性

  16. 16

    带字符串Bind to Int属性的WPF组合框

  17. 17

    将 WPF 组合框绑定到用户设置属性

  18. 18

    更改集合时,WPF组合框未更新

  19. 19

    WPF DataGridTemplateColumn组合框更新所有行

  20. 20

    WPF 组合框 SelectedItem 绑定不会从代码更新

  21. 21

    WPF组合框问题

  22. 22

    WPF组合框值

  23. 23

    由于大小写不同,WPF组合框在ItemSource中找不到SelectedValue

  24. 24

    从 ViewModel 属性绑定 WPF 中的 ImageAwesome 对象

  25. 25

    WPF DataGridCheckBoxColumn的状态不会从ViewModel更新

  26. 26

    如何将组合框的selectedValue转换为整数?

  27. 27

    组合框的SelectedValue返回一个意外值

  28. 28

    vb.net组合框selectedvalue事件错误

  29. 29

    包含组合框的ItemTemplate-如何绑定到SelectedValue?

热门标签

归档