2012-07-16 84 views
2

我在WP7中構建一個簡單的粗糙表單存在問題。我花了很多時間將Enum顯示到列表選擇器中,現在我在嘗試綁定到(IsolatedStorage)對象時看到InvalidCastException。Windows Phone 7 ListPicker InvalidCastException

public class Bath { 
    public string Colour { get; set; } 
    public WaterType WaterType { get; set; } 
} 

public enum WaterType { 
    Hot, 
    Cold 
} 

枚舉綁定到ListPicker,但因爲沒有enum.GetValues()在WP7這不是一個簡單的任務。

我有一個簡單類型的類...

public class TypeList 
    { 
     public string Name { get; set; } 
    } 

而在我的視圖模型,我的ObservableCollection和枚舉嘲笑值...

private ObservableCollection<TypeList> _WaterTypeList; 
    public ObservableCollection<TypeList> WaterTypeList 
    { 
     get { return _WaterTypeList; } 
     set 
     { 
      _WaterTypeList= value; 
      NotifyPropertyChanged("WaterTypeList"); 
     } 
    } 

    public void LoadCollectionsFromDatabase() 
    { 
     ObservableCollection<TypeList> wTypeList = new ObservableCollection<WaterTypeList>(); 
     wTypeList.Add(new TypeList{ Name = WaterType.Hot.ToString() }); 
     wTypeList.Add(new TypeList{ Name = WaterType.Income.ToString() }); 
     WaterTypeList = new ObservableCollection<TypeList>(wTypeList); 
    } 

最後,我的XAML包含列表框...

<toolkit:ListPicker 
      x:Name="BathTypeListPicker" 
      ItemsSource="{Binding WaterTypeList}" 
      DisplayMemberPath="Name"> 
     </toolkit:ListPicker> 

我不確定上述是否是最佳做法,事實上如果上述是第問題,但上述確實給了我一個填充ListPicker。

最後,當提交表單時,cast會導致InvalidCastException。

private void SaveAppBarButton_Click(object sender, EventArgs e) 
{ 
    var xyz = WaterTypeList.SelectedItem; // type AppName.Model.typeList 

     Bath b = new Bath 
     { 
      Colour = ColourTextBox.Text ?? "Black", 
      WaterType = (WaterType)WaterTypeListPicker.SelectedItem 
     }; 

     App.ViewModel.EditBath(b); 
     NavigationService.Navigate(new Uri("/Somewhere.xaml", UriKind.Relative)); 
    } 
} 

有沒有人遇到類似的問題,並可以提供建議。我看到我的opions將集中精力從ListPicker轉換有意義的東西,還是應該重新思考ListPicker的填充方式?

回答

1

WaterTypeListPicker.SelectedItem的是TypeList類型的對象,因此它不能被轉換爲WaterType類型的對象。

爲了轉換回一個WaterType,你可以取代你的施法:

WaterType = (WaterType)WaterTypeListPicker.SelectedItem 

有:

WaterType = (WaterType)Enum.Parse(
           typeof(WaterType), 
           ((TypeList)WaterTypeListPicker.SelectedItem).Name, 
           false) 
+0

那真棒,真該感謝,因爲我是很好,真正卡住! – Gavin 2012-07-17 16:04:22

3

據我所見,WaterTypeList是一個ObservableCollection,它是一個Type並且一個可觀察的集合沒有SelectedItem屬性。

您的Bath類有一個WaterType接受WaterType屬性,並且您正試圖將WaterTypeListPicker.SelectedItem投射到它..所以我假設您的WatertypeListPicker是您的ListBox?

如果是這樣,那麼你做錯了,因爲你的ListBox的itemssource綁定到一個類,並且你正在嘗試添加一個到你的WaterType屬性。

我會做的是說,

Bath b = new Bath 
     { 
      Colour = ColourTextBox.Text ?? "Black", 
      WaterType = WaterTypeListPicker.SelectedItem 
     }; 

,要麼是我巴斯WaterType的屬性更改爲類型串所以上面的代碼會工作。但是我不會推薦另外一個類來包裝這個枚舉來顯示它到列表框。

我會做的是創造一個EnumHelper

public static class EnumExtensions 
{ 
    public static T[] GetEnumValues<T>() 
    { 
     var type = typeof(T); 
     if (!type.IsEnum) 
      throw new ArgumentException("Type '" + type.Name + "' is not an enum"); 

     return (
      from field in type.GetFields(BindingFlags.Public | BindingFlags.Static) 
      where field.IsLiteral 
      select (T)field.GetValue(null) 
     ).ToArray(); 
    } 

    public static string[] GetEnumStrings<T>() 
    { 
     var type = typeof(T); 
     if (!type.IsEnum) 
      throw new ArgumentException("Type '" + type.Name + "' is not an enum"); 

     return (
      from field in type.GetFields(BindingFlags.Public | BindingFlags.Static) 
      where field.IsLiteral 
      select field.Name 
     ).ToArray(); 
    } 
} 

並將其綁定到一個集合

視圖模型

public IEnumerable<string> Priority 
     { 
      get { return EnumExtensions.GetEnumValues<Priority>().Select(priority => priority.ToString()); } 

public string SelectedPriority 
     { 
      get { return Model.Priority; } 
      set { Model.Priority = value; } 
     } 

這樣。

我的XAML

<telerikInput:RadListPicker SelectedItem="{Binding SelectedPriority, Mode=TwoWay}" ItemsSource="{Binding Priority}" Grid.Column="1" Grid.Row="4"/>