【问题标题】:Windows Phone 7 ListPicker InvalidCastExceptionWindows Phone 7 ListPicker InvalidCastException
【发布时间】:2012-07-16 23:26:38
【问题描述】:

我在 WP7 中构建简单的 crud 表单时遇到问题。我花了很多时间将枚举显示到列表选择器中,现在我在尝试绑定到 (IsolatedStorage) 对象时看到了 InvalidCastException。

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

public enum WaterType {
   Hot,
   Cold
}

枚举绑定到 ListPicker,但由于 WP7 中没有 enum.GetValues(),这不是一个简单的任务。

我有一个简单的类型类...

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。

最后,当提交表单时,强制转换会导致 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));
    }
}

有没有人遇到过类似的问题,可以提供建议。我发现我的选择是专注于从 ListPicker 中投射一些有意义的东西,还是我应该重新考虑 ListPicker 的填充方式?

【问题讨论】:

    标签: c# silverlight windows-phone-7 data-binding


    【解决方案1】:

    据我所知,WaterTypeList 是一个 ObservableCollection,它是一个类型,而一个可观察集合没有 SelectedItem 属性。

    您的 Bath 类有一个接受 WaterType 属性的 WaterType,并且您正在尝试将 WaterTypeListPicker.SelectedItem 投射到它。所以我假设您的 WatertypeListPicker 是您的 ListBox?

    如果是,那么你做错了,因为你的 ListBox 的 itemssource 绑定到一个类,而你正试图将 a 添加到你的 WaterType 属性。

    我会说,

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

    要么将我的 Bath 的 WaterType 属性更改为 TypeList,这样上面的代码才能正常工作。但我不建议做另一个类来包装枚举只是为了将它显示到列表框。

    我要做的是创建一个 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();
        }
    }
    

    并将其绑定到一个集合

    我的ViewModel

    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"/>
    

    【讨论】:

      【解决方案2】:

      WaterTypeListPicker.SelectedItemTypeList 类型的对象,因此不能转换为 WaterType 类型的对象。

      为了转换回 WaterType,您可以替换您的演员:

      WaterType = (WaterType)WaterTypeListPicker.SelectedItem
      

      与:

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

      【讨论】:

      • 太棒了,真的感谢我,因为我很好,真的被困住了!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多