2012-07-16 89 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"/>