Mvvm SelectedItem必须始终设置为有效值

Mvvm SelectedItem必须始终设置为有效值,mvvm,windows-phone,Mvvm,Windows Phone,我有两个viewmodel,在第一个viewmodel上有一个列表框: <ListBox x:Name="MainMenu" toolkits:TiltEffect.IsTiltEnabled="True" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" ItemTemplate="{StaticResource MainMenu}" ItemsSource="{Binding Categories}" Margin="0,

我有两个viewmodel,在第一个viewmodel上有一个列表框:

<ListBox x:Name="MainMenu" toolkits:TiltEffect.IsTiltEnabled="True" 
 SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
 ItemTemplate="{StaticResource MainMenu}" 
 ItemsSource="{Binding Categories}" Margin="0,97,0,0" 
 Tap="MainMenu_Tap">
第二视图模型

private CategoryModel _selectedItem = null;
public CategoryModel SelectedItem
{
    get { return _selectedItem; }
    set
    {
        if (_selectedItem == value)
        {
            return;
        }

        var oldValue = _selectedItem;
        _selectedItem = value;

        RaisePropertyChanged("SelectedItem", oldValue, value, true);
    }
}
private CategoryModel _item = null;
public CategoryModel Item
{
    get { return _item; }
    set
    {
        if (_item == value)
        {
            return;
        }

        var oldValue = _item;
        _item = value;

        // Update bindings, no broadcast
        RaisePropertyChanged("Item");
    }
}

编辑

当我将第二页中的listpicker更改为Listbox时,它工作得非常好


所以这是一个问题。如何使用listpicker实现这一点?

我认为您混淆了视图和视图模型

因为您要在XAML中绑定所选项,所以在解析XAML并创建页面时,它试图绑定到集合中尚未创建的项。这就是为什么在代码隐藏中设置此错误时,有关该错误的注释建议了一种解决方法

在第一页的
点击
处理程序中,我假设您正在将所选项目的一些详细信息传递到第二页。因此,您可以删除所选项目的XAML绑定,并在第二页的
OnNavigatedTo
事件处理程序中,在知道已填充项目资源后,在代码中设置绑定


可选地,您可以考虑让两个页面共享同一个VIEW模型实例。

ListPoCter使用ItEM.Index来获取应该选择的项目实例的索引。

如果实例不匹配(它不是集合中的对象实例),IndexOf将返回-1,并抛出InvalidOperationException,并显示消息:“SelectedItem必须始终设置为有效值”

重写集合中类型的Equals方法,它将按预期工作

例如:

public override bool Equals(object obj)
{
         var target = obj as ThisTarget;
         if (target == null)
             return false;

         if (this.ID == target.ID)
             return true;

         return false;
 }
希望能有帮助

public override bool Equals(object obj)
{
         var target = obj as ThisTarget;
         if (target == null)
             return false;

         if (this.ID == target.ID)
             return true;

         return false;
 }