2011-10-10 48 views
10

我在Windows Phone 7應用程序中有一個頁面,用戶可以在其中編輯或刪除一個Transaction對象。 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事件是在八月/ 2011版的WPF的一個bug修復工具包的Windows Phone和很簡單:

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

如果用戶編輯的交易,一切都很好,但如果用戶試圖刪除它,我得到一個錯誤說「的SelectedItem必須始終設置爲有效值「。

下面的代碼,如果用戶點擊刪除按鈕在appbar在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,在那裏我得到了錯誤的路線是這樣的:

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

在propertyName的屬性值是「類別」。它看起來像是在刪除對象時發送類別和帳戶的屬性更改事件,並且由於listpicker處於雙向模式,所以在處理它時遇到了一些麻煩。我怎麼修復它?我需要一些幫助。

+0

您可以將完整的XAML?或者如果它太長,只要我們可以看到'{Binding Account,Mode = TwoWay}'和'{Binding Category,Mode = TwoWay}'指的是什麼,部分XAML就可以。 – Amry

回答

1

問題是ListPicker期望SelectedItemListPickerItem,而您將其綁定到Transaction類型的對象。您可以通過綁定到SelectedIndex屬性來解決問題,然後根據索引從ViewModel中選擇適當的對象。

此外,如果您已經定義了Tap處理的原因是因爲,當放置在ScrollViewerListPicker不開的bug,看看patch ID 10247。如果您使用該補丁重新編譯工具包,它可以解決問題。

+0

'ListPicker.SelectedItem'也可以綁定到數據對象,而不僅僅是'ListPickerItem'。 – Amry

+0

@Amry你嘗試過嗎?我有完全相同的問題,必須解決使用'SelectedIndex' – Praetorian

+0

如果'ListPicker'是數據綁定,那麼與'SelectedItem'一起使用數據對象應該可以正常工作。也許你可以爲你的情況開一個新的問題。 :) – Amry

2

只有兩項檢查其拋出InvalidOperationException異常上的SelectedItem

  1. Listpicker項目爲空 (聲明:屬性事宜命令,如果將selectedItem必須經過的ItemSource出現 (程序化:確保的ItemSource加載)
  2. Listpicker上的項目適用INDEXOF設置選定的項目。所以,必要時請確保你重寫equals。

調試與開左表istpicker。項目和覆蓋equals方法將幫助我們找出問題

+0

另請注意:如果你綁定到一個子屬性,你還需要初始化它,否則你會遇到同樣的錯誤(因爲你的第一個屬性爲空)。 – kamranicus

12

此錯誤也可以通過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}" /> 
+1

是的,這顯然是.NET控件中的一個錯誤,因爲它應該處理這樣的場景而不會崩潰......(設計你自己的控件時要考慮到這個問題:) –

+0

這個解決方案爲我做了。 –

3

ListPicker使用Items.IndexOf拿到我它應該選擇的項目實例的索引。

如果實例不匹配(它不是集合中的對象實例),IndexOf將返回-1,並且引發InvalidOperationException異常:「SelectedItem必須始終設置爲有效值」。

覆蓋集合中項目類型的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; 
} 

希望它可以幫助

相關問題