SelectedItem必须始终设置为一个有效值

本文关键字:一个 有效值 设置 SelectedItem | 更新日期: 2023-09-27 18:11:05

我在Windows Phone 7应用程序中有一个页面,用户可以在其中编辑或删除Transaction对象。Transaction对象是一个与Account类和Category类有关系的Linq-to-Sql类。在页面中,我使用ListPicker让用户为给定的事务选择帐户和类别,如下所示:

<toolkit:ListPicker Grid.Row="1" FullModeHeader="Choose the Account" FullModeItemTemplate="{StaticResource FullModeItemTemplate}" ExpansionMode="FullScreenOnly" Background="#26000000" Margin="10,0,10,0" Name="Account" SelectedItem="{Binding Account, Mode=TwoWay}" Tap="ListPicker_Tap" />
<toolkit:ListPicker Grid.Row="7" FullModeHeader="Choose the Category" FullModeItemTemplate="{StaticResource FullModeItemTemplate}" ExpansionMode="FullScreenOnly" Background="#26000000" Margin="10,0,10,0" Name="Category" SelectedItem="{Binding Category, Mode=TwoWay}" Tap="ListPicker_Tap" />

ListPicker_Tap事件修复了2011年8月WPF Toolkit for Windows Phone版本中的一个bug,内容如下:

    private void ListPicker_Tap(object sender, System.Windows.Input.GestureEventArgs e)
    {
        ListPicker lp = (ListPicker)sender; 
        lp.Open();
    }

如果用户编辑事务,一切都很好,但如果用户试图删除它,我得到一个错误说"SelectedItem必须始终设置为一个有效值"。

如果用户单击transactionpage . example .cs中的appbar中的删除按钮,则代码如下:

    private void appBarDelete_Click(object sender, EventArgs e)
    {
        MessageBoxResult result = MessageBox.Show("Are you sure?'n", "Confirm", MessageBoxButton.OKCancel);
        if (result == MessageBoxResult.OK)
        {
            App.ViewModel.DeleteTransaction(transaction);
        }
        NavigationService.GoBack();
    }

我的视图模型。DeleteTransaction方法:

    public void DeleteTransaction(Transaction transaction)
    {
        AllTransactions.Remove(transaction);
        transactionRepository.Delete(transaction);
    }
transactionRepository

。删除方法:

    public void Delete(Transaction transaction)
    {
        Context.Transactions.DeleteOnSubmit(transaction);
        Context.SubmitChanges();
    }

我在Context.SubmitChanges()执行中收到错误,调试指向Transaction类中的NotifyPropertyChanged,我得到错误的行是:

    protected virtual void SendPropertyChanged(String propertyName)
    {
        if ((this.PropertyChanged != null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

propertyName属性的值为"Category"。看起来,当删除对象发送类别和帐户的属性更改事件时,因为列表选择器处于双向模式,它在处理它时遇到了一些麻烦。我怎样才能修好它呢?我需要帮助。

SelectedItem必须始终设置为一个有效值

这个错误也可能是由XAML属性的顺序引起的:

这不起作用(抛出异常,因为当设置SelectedItem时ItemsSource为null):

<toolkit:ListPicker DisplayMemberPath="Title" SelectionMode="Single" 
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}"
ItemsSource="{Binding Categories}" />

itemssource首先初始化:

<toolkit:ListPicker DisplayMemberPath="Title" SelectionMode="Single" 
ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" />

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

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

Override Equals方法,它将按预期工作。

的例子:

public override bool Equals(object obj)
{
         var target = obj as ThisType;
         if (target == null)
             return false;
         if (this.ID == target.ID)
             return true;
         return false;
 }

希望有所帮助

在SelectedItem

上只有两个检查会抛出InvalidOperationException
  1. 列表选择器项为空(声明性:属性的顺序很重要。如果被选中,item必须出现在itemsource之后(可编程:确保itemsource已加载)
  2. Listpicker在Items上应用Indexof来设置所选的item。因此,如果有必要,请确保重写Equals。

在列表选择器上调试手表。项和重写的Equals方法将帮助我们识别问题

问题是ListPicker期望SelectedItemListPickerItem,而您将其绑定到Transaction类型的对象。您可以通过绑定到SelectedIndex属性来解决这个问题,然后根据索引从ViewModel中选择适当的对象。

另外,如果您定义Tap处理程序的原因是因为ListPicker在放置在ScrollViewer中时不打开的错误,请查看补丁ID 10247。如果您使用该补丁重新编译工具包,它将修复问题。