Xaml 绑定ListPicker.SelectedIndex问题
我正在尝试在WindowsPhone7用户控件中对ListPicker的SelectedIndex属性进行双向绑定Xaml 绑定ListPicker.SelectedIndex问题,xaml,windows-phone-7,binding,listpicker,Xaml,Windows Phone 7,Binding,Listpicker,我正在尝试在WindowsPhone7用户控件中对ListPicker的SelectedIndex属性进行双向绑定 <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
<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时会引发以下异常:
SelectedIndex必须始终设置为有效值。
<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>
这是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中的代码
<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>
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;
}
}
private observeCollection myList=null;
公共可观测集合MyList
{
获取{返回this.myList;}
设置
{
if(值!=this.myList)
{
this.myList=值;
NotifyPropertyChanged(“MyList”);
this.PickerSelectedIndex=0;
}
}
}
私有整数选择器selectedIndex=0;
公共整数选择器选择索引
{
得到
{
返回此.pickerSelectedIndex;
}
设置
{
this.pickerSelectedIndex=值;
}
}
在选择器selectedIndex.get中放置断点
我可以看到它已正确返回(0
)。
我确信问题是SelectedIndex=“{Binding PickerSelectedIndex,Mode=TwoWay}”
,因为删除这一行可以解决问题,并且我可以看到ListPicker正确加载了MyList中的数据
<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>
我看不出问题出在哪里…我的猜测是,在创建绑定时,在项目存在之前,应用绑定的默认值为零。因此,它试图在创建第一个项之前选择该项(索引为零)
<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>
尝试确保PickerSelectedIndex
的ViewModel属性默认为-1。您可能还希望延迟设置绑定,直到创建项目。马特·莱西是对的;绑定发生在数据项填充之前&因此出现错误。如果您有SelectionChanged的事件处理程序,您会注意到当页面/列表选择器加载时,其中的断点将被命中。以下是解决此初始化问题的一种方法:
<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>
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.
}
}
}
在
itemsource
之后移动SelectedIndex
解决了问题
<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>
这是工作片段
<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>
<toolkit:ListPicker
Grid.Row="0"
x:Name="List1"
SelectionChanged="Picker_SelectionChanged"
ItemTemplate="{StaticResource PickerTemplate}"
ItemsSource="{Binding MyList}"
SelectedIndex="{Binding PickerSelectedIndex, Mode=TwoWay}"/>
有人对此有什么解释吗?我也有同样的问题,XAML中属性的排序没有帮助。在我的例子中,我将ItemsSource绑定到StaticResource上的一个属性,但将SelectedIndex绑定到页面的ViewModel属性。当我将ItemsSource的绑定更改为绑定到ViewModel本身的一个属性(即复制了StaticResource的一个属性)时,我的问题就消失了,我也能够对SelectedIndex执行双向绑定 我发现我的应用程序也存在同样的问题。
<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>
但我注意到,当我在ViewModel中删除列表中绑定到ListPicker的所有元素时,就会发生这种情况。
因此,没有必要将SelectedIndex与另一个属性绑定,因为问题只取决于绑定的列表。
以下是我的代码,对我来说很好:
<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>
<toolkit:ListPicker x:Name="ListaCorsi"
SelectionChanged="ListaCorsi_SelectionChanged"
ItemsSource="{Binding ListaCorsiUser}"
SelectionMode="Single"
ItemTemplate="{StaticResource CorsiDataTemplate}"
ItemsPanel="{StaticResource ItemsPanelTemplateListaCorsi}"/>
其中,Corsi是列表的类类型
<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>
这里是ListPicker模板:
<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>
<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的列表中放置一个伪空元素,以避免收到本文中提到的错误
<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>
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()});
}
----
}
if(this.CorsoSelected!=null)
{
---
List corsi=新列表(DBHelper.GetCorsiByUserId(PassaggioValori.UserId));
如果(corsi.Count>0)
{
this.ListaCorsiUser=新的可观测集合(corsi);
}
其他的
{
this.ListaCorsiUser=newobserveCollection(new List(){new Corsi()});
}
----
}
奇怪的是,如果加载页面时列表为空,则什么也不会发生,相反,当我从列表中删除最后一个元素时,应用程序引发了异常“SelectedItem必须始终设置为有效值”。
现在问题解决了。这可能没有什么帮助,但我发现有趣的是,这段代码在WPF中似乎工作得很好。对不起,我是Silverlight开发人员,您能解释一下“PickerSelectedIndex的ViewModel属性”是什么意思吗?行“private int PickerSelectedIndex=0;”将属性设置为默认值为零。这就是我所指的。如果保留SelectedIndex绑定,但去掉ItemTemplate,会发生什么?我不编写WP7,但在WPF中,这段代码(减去ItemTemplate)可以正常工作。删除
ItemTemplate=“{StaticResource PickerTemplate}”
并不能解决问题。。。无论如何,谢谢你!我也有同样的问题。很奇怪,这似乎取决于xaml属性的顺序。。。我认为这是一个错误,因为xaml属性应该独立于它们的顺序工作。事实上,这是工作在wpf没有问题也表明了这一点。是的,工作为我太。最初我是绑定SelectedIndex={binding Source={StaticResource AppSettings},Path=ChosenFavorite,Mode=TwoWay}。我必须将值的检索移到视图模型。
<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>