ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – UWP – x:绑定模式= TwoWay抛出没有转换器的错误

2019-06-11 17:55:59  阅读:198  来源: 互联网

标签:c win-universal-app


对此有类似的问题,但答案似乎与原始问题不符.

我有一个DataTemplate,里面有3个组合框.前两个工作正常,但第三个抛出编译器错误.

<ComboBox ItemsSource="{x:Bind ListOne, Mode=OneWay}" 
              SelectedItem="{Binding SelectedOne, Mode=TwoWay}"
              DisplayMemberPath="Name"/>
<ComboBox ItemsSource="{x:Bind ListTwo}" 
              SelectedItem="{x:Bind SelectedTwo, Mode=TwoWay, Converter={StaticResource GenericConverter}}"
              DisplayMemberPath="Name"/>
<ComboBox ItemsSource="{x:Bind ListThree}" 
              SelectedItem="{x:Bind SelectedThree, Mode=TwoWay}"
              DisplayMemberPath="Name"/>

对于ListOne,“绑定”工作原理完美.

对于ListTwo,“x:Bind”仅在添加值转换器时有效. “GenericConverter”只返回传入的“值”.除此之外,它什么都不做.

对于没有值转换器的ListThree,编译器会抛出错误:

“Invalid binding path ‘SelectedThree’: Cannot bind type ‘IdNameVm’ to
‘SystemObject’ without a converter.

在所有情况下,ItemSource都是ObservableCollection,所选项的类型为IdNameVm.

使用转换器工作,但是被迫在x上放置一个虚拟转换器感觉不对:绑定只是为了让XAML进行编译.

根据要求,以下是ObservableCollection的定义方式以及IdNameVm:

public ObservableCollection<IdNameVm> ListOne { get; set; }


public class IdNameVm : BindableBase
{
    private int _id;
    private string _name;

    public int Id
    {
        get { return _id; }
        set { Set(ref _id, value); }
    }

    public string Name
    {
        get { return _name; }
        set { Set(ref _name, value); }
    }

    protected bool Equals(IdNameVm other)
    {
        return Id == other.Id;
    }

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

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = Id;
            return hashCode;
        }
    }
}

解决方法:

如果您查看ComboBox的文档,您将看到ItemsSource和SelectedItem属性都是类型对象.控件运行时不知道它正在处理哪种类型的视图模型.所以你基本上可以将任何类型的集合传递给ItemsSource.并且SelectedItem在不知道它正在处理什么类型的对象的情况下工作.

这种行为适用于传统的双向{Binding},因为在运行时评估绑定.所以{Binding}可以在运行时将SelectItem的对象类型转换为IdNameVm.

但是,{x:Bind}的情况有点不同.正如您已经注意到单向绑定有效 – 这是因为您的ObservableCollection可以隐式转换为object(ItemsSource的类型)和IdNameVm转换为object(SelectedItem的类型).但是双向绑定将不再起作用,因为编译器无法将对象(SelectedItem的类型)强制转换为IdNameVm.你需要一个转换器.

这就像你可以在C#中做到这一点:

IdNameVm vm = new IdNameVm();
object selectedItem = vm;

但你做不到:

IdNameVm vm = new IdNameVm();
object selectedItem = vm;
IdNameVm vm2 = selectedItem; // You need: IdNameVm vm2 = (IdNameVm)selectedItem;

评论中的演员阵容是XAML中的转换器.

最简单的方法是在这些情况下使用传统的{Binding}.

标签:c,win-universal-app
来源: https://codeday.me/bug/20190611/1220122.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有