SelectedItem必须始终设置为有效值

时间:2013-03-07 02:15:04

标签: 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,97,0,0" 
 Tap="MainMenu_Tap">

在第二页中,我有一个listpicker

<toolkit:ListPicker Margin="0,153,0,0" Background="{StaticResource PhoneAccentBrush}" VerticalAlignment="Top"
 ItemsSource="{Binding Categories}"
 SelectedItem="{Binding Item}"
 ItemTemplate="{StaticResource CategorySelector}"
 FullModeHeader="Category" 
 FullModeItemTemplate="{StaticResource FullCategorySelector}"
 BorderBrush="{StaticResource PhoneAccentBrush}"/>

我想要的是当我导航到第二页时,将在第二页中选择第一页中的所选项目。但是当我导航到第二页时,我总是得到所选项目必须始终设置为有效值。

第一个视图模型

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

enter image description here

修改

当我将第二页中的listpicker更改为Listbox时,它的效果非常好。

所以这是一个问题enter link description here。我该怎么做才能让这个东西与listpicker一起工作?

2 个答案:

答案 0 :(得分:0)

我认为你会混淆视图和视图模型。

因为您正在绑定XAML中的选定项目,所以在解析XAML并创建页面时,它会尝试绑定到尚未创建的集合中的项目。这就是为什么关于bug的评论建议在代码背后设置它时的解决方法。

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

或者,您可以考虑让两个页面共享相同的viewmodel实例。

答案 1 :(得分:0)

ListPicker使用Items.IndexOf来获取应该选择的项目实例的索引。

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

覆盖集合中类型的等于方法,它将按预期工作。

示例:

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

希望有所帮助