8

Windows Phone 7 UserControl で ListPicker の SelectedIndex 属性の双方向バインディングを実行しようとしています。

DataContext を設定すると、次の例外が発生します。 SelectedIndex must always be set to a valid value.

これは XAML コードです

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <toolkit:ListPicker
        Grid.Row="0"
        x:Name="List1"
        SelectionChanged="Picker_SelectionChanged"
        SelectedIndex="{Binding PickerSelectedIndex, Mode=TwoWay}"
        ItemTemplate="{StaticResource PickerTemplate}"
        ItemsSource="{Binding MyList}"/>
</Grid>

そして、DataContext のコード ビハインド

    private ObservableCollection<MyClass> myList = null;
    public ObservableCollection<MyClass> MyList
    {
        get { return this.myList; }
        set
        {
            if (value != this.myList)
            {
                this.myList= value;
                NotifyPropertyChanged("MyList");

                this.PickerSelectedIndex = 0;
            }
        }
    }

    private int pickerSelectedIndex = 0;
    public int PickerSelectedIndex
    {
        get
        {
            return this.pickerSelectedIndex;
        }
        set
        {
            this.pickerSelectedIndex= value;
        }
    }

ブレークポイントPickerSelectedIndex.getを入れると、正しく返されることがわかります ( 0)。この行を削除すると問題がSelectedIndex="{Binding PickerSelectedIndex, Mode=TwoWay}"解決し、ListPicker に MyList のデータが正しく読み込まれていることがわかります。

どこが問題なのか見当がつかない…

4

5 に答える 5

5

問題を解決したSelectedIndex後に移動します。ItemsSource

これは作業スニペットです

<toolkit:ListPicker
    Grid.Row="0"
    x:Name="List1"
    SelectionChanged="Picker_SelectionChanged"
    ItemTemplate="{StaticResource PickerTemplate}"
    ItemsSource="{Binding MyList}"
    SelectedIndex="{Binding PickerSelectedIndex, Mode=TwoWay}"/>

誰でもこれについて説明がありますか?

于 2011-05-18T07:09:33.970 に答える
3

私の推測では、作成時およびアイテムが存在する前に、デフォルト値ゼロでバインディングが適用されていると思います。したがって、そのアイテムが作成される前に、最初のアイテム (ゼロ インデックス) を選択しようとしています。

の ViewModel プロパティがPickerSelectedIndexデフォルトで -1 になっていることを確認してください。
アイテムが作成されるまでバインディングの設定を遅らせたい場合もあります。

于 2011-05-17T15:15:46.770 に答える
1

マット・レイシーは正しいです。バインディングは、データアイテムが入力される前に発生するため、エラーが発生します。SelectionChangedのイベントハンドラーがある場合、ページ/リストピッカーがロードされるときにブレークポイントがヒットすることに気付くでしょう。この初期化の問題を回避する1つの方法は次のとおりです。

private void SomeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Make sure we don't handle the event during initiation.
        if (e.RemovedItems != null && e.RemovedItems.Count > 0)
        {
            if (this.SomeListPicker.SelectedItem != null)
            {
               // Do actual stuff.                    
            }
         }            
    }
于 2011-05-17T17:03:08.557 に答える
1

同じ問題があり、XAML でのプロパティの順序付けは役に立ちませんでした。私の場合、ItemsSource を StaticResource のプロパティにバインドしていましたが、SelectedIndex をページの ViewModel のプロパティにバインドしていました。ItemsSource のバインディングを ViewModel 自体のプロパティにバインドするように変更した (つまり、StaticResource のプロパティを複製した) 瞬間、問題はなくなり、SelectedIndex でも双方向バインディングを実行できるようになりました。

于 2011-06-01T13:10:00.983 に答える
1

アプリで同じ問題が見つかりました。しかし、ViewModel の ListPicker にバインドされているリストのすべての要素を削除すると、この問題が発生することに気付きました。したがって、SelectedIndex を別のプロパティにバインドする必要はありません。これは、問題がバインドされたリストのみに依存するためです。これが私にとってうまくいく私のコードです:

<toolkit:ListPicker x:Name="ListaCorsi"
                                SelectionChanged="ListaCorsi_SelectionChanged"
                                ItemsSource="{Binding ListaCorsiUser}"
                                SelectionMode="Single" 
                                ItemTemplate="{StaticResource CorsiDataTemplate}" 
                                ItemsPanel="{StaticResource ItemsPanelTemplateListaCorsi}"/>

ビューモデルのリスト:

private ObservableCollection<Corsi> _listaCorsiUser;
    public ObservableCollection<Corsi> ListaCorsiUser 
    {
        get { return _listaCorsiUser; }
        set
        {
            _listaCorsiUser = value;
            OnPropertyChanged("ListaCorsiUser");
        }
    }

SelectionChanged のハンドラー:

void ListaCorsi_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
            if (ListaCorsi.SelectedItem != null)
            {
                ---
                this.CorsoSelected = ListaCorsi.SelectedItem as Corsi;
            }
    }

ここで、Corsi はリストのクラス タイプです。

ここで ListPicker テンプレート:

<DataTemplate x:Key="CorsiDataTemplate">
        <Grid>
            <Grid.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Black" Offset="0"/>
                    <GradientStop Color="#FF3523FF" Offset="0.25"/>
                    <GradientStop Color="Black" Offset="1"/>
                    <GradientStop Color="#FF3523FF" Offset="0.75"/>
                </LinearGradientBrush>
            </Grid.Background>
            <TextBlock TextWrapping="Wrap" Text="{Binding NomeCorso}" FontSize="24" FontFamily="Freestyle Script" TextAlignment="Center"/>
        </Grid>
    </DataTemplate>

最後に、IsolatedStorage によって返されたリストが空かどうかをチェックするメソッド delete が空である場合は、この投稿で言及されているエラーを受信しないように、ListPicker にバインドされたリストに偽の空の要素を配置します。

if (this.CorsoSelected != null)
        {
            ---

                    List<Corsi> corsi = new List<Corsi>(DBHelper.GetCorsiByUserId(PassaggioValori.UserId));
                    if (corsi.Count > 0)
                    {
                        this.ListaCorsiUser = new ObservableCollection<Corsi>(corsi);

                    }
                    else
                    {
                        this.ListaCorsiUser = new ObservableCollection<Corsi>(new List<Corsi>() { new Corsi()});

                    }
                ----
        }

奇妙なことに、ページが読み込まれたときにリストが空の場合、何も起こらず、リストから最後の要素を削除すると、アプリケーションは例外「SelectedItem は常に有効な値に設定する必要があります」を発生させました。これで問題は解決しました。

于 2012-07-28T08:22:32.980 に答える