组合框不从viewmodel更新到.net 4.5中查看

时间:2012-08-17 13:56:02

标签: c# .net wpf mvvm

我在wpf中有一个ComboBox,它在视图和视图模型之间绑定。 在win7下运行.net 4一切正常,但在Windows 8下运行我的应用程序,组合框似乎无法从视图模型中获取正确的选定项目。

进入视图时,组合框会从视图模型中请求所选项目 返回选定的项目,覆盖“等于”的方法返回true 视图中的组合框要么不注册,要么忽略它,接下来发生的事情是View将视图模型中的“Selected Item”设置为“NULL”。

我是否有其他方式可以达到要求,或者只是在.net 4.5下运行.net 4应用程序的一个错误,我将不得不忍受?

这是来源。 注意我直接绑定到item类而不是enum,因此我可以访问[Description]标签以获得更好的组合框中的项目名称。

查看

<Controls:KNComboBox Style="{DynamicResource FlowMenuComboBox}" SelectedItem="{Binding ItemsOrder}" ItemsSource="{Binding ItemsOrderValues}" Margin="10,0,0,10"
                                             DisplayMemberPath="Description" SelectedValuePath="{Binding Path=EnumObject}" DisplayString="Sort By:"/>

查看模型

private ItemsOrderByItem _itemsOrder;
    public ItemsOrderByItem ItemsOrder
    {
        get
        {
            return _itemsOrder;
        }
        set
        {
            _itemsOrder = value;
            RaisePropertyChanged("ItemsOrder");
            //Methods Called Here Not Important To Question
        }
    }
    public List<ItemsOrderByItem> ItemsOrderValues
    {
        get
        {
            List<ItemsOrderByItem> enumItems = new List<ItemsOrderByItem>();
            foreach (ItemsOrderBy enumValue in Enum.GetValues(typeof(ItemsOrderBy)))
            {
                enumItems.Add(new ItemsOrderByItem(enumValue));
            }
            return enumItems;
        }
    }

枚举

public enum ItemsOrderBy
{
    [Description("Name")]
    Name,
    [Description("Date Added")]
    DateAdded        
}

项目类

public class ItemsOrderByItem
{
    public ItemsOrderByItem(ItemsOrderBy enumValue)
    {
        EnumObject = enumValue;
    }
    public ItemsOrderBy EnumObject;
    public string Description
    {
        get
        {
            return EnumExtension.GetEnumDescription<ItemsOrderBy>(EnumObject);
        }
    }

    public override string ToString()
    {
        return Description;
    }

    public override bool Equals(object obj)
    {
        if (obj is ItemsOrderByItem)
        {
            return ((ItemsOrderByItem)obj).EnumObject == EnumObject;
        }
        else
        {
            return false;
        }
    }
}  

1 个答案:

答案 0 :(得分:1)

检查帖子中的代码段会发现几个问题:

  1. 每次查询时,ItemsOrderValues属性都会返回一个新值。这相当于在不引发属性更改通知的情况下更改值。数据绑定客户端将会混淆。

  2. {Binding Path = EnumObject}无法正常工作。绑定路径使用属性; EnumObject是一个字段。

  3. SelectedValuePath具有类型字符串。对EnumObject的绑定(如果有效)会生成ItemsOrderBy类型的对象。在类型转换之后,这会将SelectedValuePath设置为&#34; Name&#34; (或者可能&#34; ItemsOrderBy.Name&#34;)。这是合法的,但可能不是你想要的。该路径应用于ItemsSource中的项目,其类型为ItemsOrderByItem;这种类型没有名为&#34; Name&#34;的属性。

  4. ItemsOrderByItem类具有可变的相等语义,即对于固定对象x和y,Object.Equals(x,y)的结果可以更改。这是因为Equals方法依赖于公共可变字段 - EnumObject。这会混淆(合法地)假设一旦x和y测试了Equal,它们将保持相等的任何代码。

  5. 该类会覆盖Equals,但不会覆盖GetHashCode。这是禁止的(参见任何一种方法的文档),因为只要在哈希表中使用实例,就会导致可怕的混淆。两个等于但具有不同哈希码的实例将破坏哈希表。 [当你解决这个问题时,请记住确保对象的哈希码永远不会改变 - 这也是一个记录的要求。]

  6. 其中,最后一个可能对您的问题负责。 WPF使用哈希表来帮助表示所选项的集合,并且在v4.5中确切的用法已更改。很可能ItemsOrderByItem类的不可靠的散列行为导致混淆。

    如果修复这些编码问题仍然无法解决您的问题,请随时打开repro项目的连接错误。