2011-10-10 4 views
10

ユーザーがトランザクションオブジェクトを編集または削除できるWindows Phone 7アプリケーションにページがあります。 Transactionオブジェクトは、AccountクラスとCategoryクラスとの関係を持つLinq-to-Sqlクラスです。ページでは、私はこのように、ユーザーが特定のトランザクションのためのアカウントとカテゴリを選択できるようにListPickerを使用します。ListPickerエラーSelectedItemは常に有効な値に設定する必要があります

<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イベントは、WPFの8月/ 2011年版のバグの修正ですWindowsの携帯電話のためのツールキットと単にこれです:

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

ユーザー編集する場合は、トランザクション、すべてが正常であるが、ユーザがそれを削除しようとすると、私はエラーを取得する「のSelectedItemは常にに設定されなければならないことを言って有効値 "とする。

ここTransactionPage.xaml.csでアプリケーションバーで削除ボタンでユーザーのクリックした場合のコードです:

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

マイViewModel.DeleteTransaction方法:

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

マイtransactionRepository.Deleteは、方法:

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

Context.SubmitChangesでエラーが表示されます。 ()の実行は、トランザクションクラスの内部NotifyPropertyChanged、私はエラーを取得する行にデバッグポイントはこれです:propertyNameので

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

は、値が「カテゴリー」である属性。オブジェクトを削除すると、カテゴリとアカウントのpropertychangedイベントが送信され、listpickerはTwoWayモードになっているため、問題を処理するのに問題があります。どうすれば修正できますか?助けが必要です。

+0

あなたは完全なXAMLを添付することができホープ?また、長すぎると、 '{Binding Account、Mode = TwoWay}'と '{Binding Category、Mode = TwoWay} 'が何を参照できるか分からない限り、部分的なXAMLは問題ありません。 – Amry

答えて

1

ListPickerSelectedItemListPickerItemであると予想していますが、これはTransactionというオブジェクトにバインドしているという問題があります。代わりにSelectedIndexプロパティにバインドして、インデックスに基づいてViewModelから適切なオブジェクトを選択して問題を回避することができます。あなたが定義されてTapハンドラを持っている理由が原因ScrollViewer内に置かれたときListPickerが開かないバグである場合も

patch ID 10247を見てみましょう。そのパッチでツールキットを再コンパイルすると、問題が修正されます。 )必ずitemsourceがロードされますのSelectedItemはitemsource後に表示されなければならない場合、属性の順序が重要 (プログラムによる:。

+0

'ListPicker.SelectedItem'は、' ListPickerItem'だけでなく、データオブジェクトにバインドすることもできます。 – Amry

+0

@Amryそれをやってみましたか?私はまったく同じ問題があり、 'SelectedIndex'を使用して回避する必要がありました – Praetorian

+0

' ListPicker'がデータバインドされている場合、 'SelectedItem'でデータオブジェクトを使用するとうまく動作するはずです。おそらく、あなたは新しい質問をあなたのために開くことができます。 :) – Amry

2

はのSelectedItemにInvalidOperationExceptionがをスローするだけで2つのチェックがあります

  1. Listpicker項目 (宣言nullであります
  2. Listpickerは、選択した項目を設定するための項目でIndexOfメソッドを適用しますので、必要に応じて等しいあなたがオーバーライドすることを確認してください。

デバッグ時計とリットルにistpicker。アイテムとオーバーライドされるメソッドが

+0

注意:サブプロパティにバインドする場合は、それを初期化する必要もあります。そうしないと、最初のプロパティがnullなので同じエラーが発生します。 – kamranicus

12

にこのエラーが問題を特定する助けになります等しいも、XAMLプロパティの順序によって発生する可能性があります

これは動作しません(のSelectedItemが設定されている場合のItemsSourceがヌルであるため、例外がスローされます):

<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}" /> 
+1

はい、これはクラッシュせずにこのようなシナリオを処理する必要があるので、明らかに.NETコントロールのバグです。(この問題を念頭に置いて独自のコントロールを設計してください:) –

+0

この解決策は私のために行いました。 –

3

ListPickerは私を取得するためにItems.IndexOfを使用しています選択すべき項目インスタンスのndex。

インスタンスが一致しない(コレクションのオブジェクトインスタンスではない)場合、IndexOfは-1を返し、 "SelectedItemは常に有効な値に設定する必要があります"というメッセージとともにInvalidOperationExceptionがスローされます。

コレクションのアイテムタイプの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; 
} 

は、それが

関連する問題