我正在尝试在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中的数据。
我看不出问题出在哪里......
答案 0 :(得分: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}"/>
有人对此有解释吗?
答案 1 :(得分:3)
我的猜测是,在创建项目和项目存在之前,绑定的默认值为零。因此,在创建该项目之前,它会尝试选择第一个项目(零索引)。
尝试确保PickerSelectedIndex
的ViewModel属性默认为-1
您可能还希望延迟设置绑定,直到创建项目。
答案 2 :(得分: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.
}
}
}
答案 3 :(得分:1)
我遇到了同样的问题,XAML中属性的排序没有帮助。在我的例子中,我将ItemsSource绑定到StaticResource上的属性,但我将SelectedIndex与我的页面的ViewModel的属性绑定。当我更改ItemsSource的绑定以绑定到ViewModel本身的属性(即复制了StaticResource的属性)时,我的问题消失了,我也能够对SelectedIndex执行双向绑定。
答案 4 :(得分: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>
并且,最后,方法delete检查IsolatedStorage返回的列表是否为空,如果是这样,我将一个假空元素放入限制到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必须始终设置为有效值”。 现在问题解决了。