2

WP7 で単純な crud フォームを作成する際に問題があります。Enum を listpicker に表示するのに多くの時間を費やしましたが、(IsolatedStorage) オブジェクトにバインドしようとすると InvalidCastException が表示されます。

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

public enum WaterType {
   Hot,
   Cold
}

enum は 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>

上記がベストプラクティスであるかどうか、実際に上記が問題の一部であるかどうかはわかりませんが、上記により、リストピッカーが作成されます。

最後に、フォームが送信されると、キャストによって 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 にデータが入力される方法を再考する必要がありますか?

4

2 に答える 2

3

私が見る限り、WaterTypeList は Type である ObservableCollection であり、監視可能なコレクションには SelectedItem プロパティがありません。

あなたの Bath クラスには WaterType プロパティを受け入れる WaterType があり、それに WaterTypeListPicker.SelectedItem をキャストしようとしています。

そうである場合は、ListBox の itemssource がクラスにバインドされていて、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();
    }
}

そしてそれをコレクションにバインドします

私のビューモデル

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"/>
于 2012-07-17T03:08:43.563 に答える
1

WaterTypeListPicker.SelectedItemtype のオブジェクトであるTypeListため、 type のオブジェクトにキャストすることはできませんWaterType

WaterType に戻すには、キャストを次のように置き換えることができます。

WaterType = (WaterType)WaterTypeListPicker.SelectedItem

と:

WaterType = (WaterType)Enum.Parse(
                               typeof(WaterType),
                               ((TypeList)WaterTypeListPicker.SelectedItem).Name,
                               false)
于 2012-07-17T08:52:26.283 に答える