修改SelectedIndex时Databound ListPicker SelectedItem变为空白
我的 Windows Phone 7 应用程序中有一个 ListPicker,其中 ItemsSource 和 SelectedIndex 属性都绑定到我的 ViewModel。 SelectedIndex 使用双向绑定。应用程序启动时会正确填充项目和 SelectedIndex。但是,当我修改 ViewModel 中的 SelectedIndex 属性时,ListPicker 的 TextBox 变为空白,就好像没有选定的项目一样。如果我进入完整模式并检查列表中选定的项目,则会选择正确的项目。
这是 ListPicker xaml 代码:
<toolkit:ListPicker Name="TheListPicker" ItemsSource="{Binding TheItems}" CacheMode="BitmapCache" FullModeHeader="{Binding Path=Resources.TheHeader, Source={StaticResource LocalizedStrings }}" SelectedIndex="{Binding TheCurrentIndex, Mode=TwoWay}" IsEnabled="{Binding IsViewEnabled}" TabIndex="0" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel x:Name="item" Orientation="Horizontal" Margin="5, 24, 0, 24">
<TextBlock Margin="15, 0, 0, 0" Text="{Binding Name}" FontSize="40" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
这是我的 ViewModel 的简化版本:
[DataMember]
public ObservableCollection<ItemEntity> TheItems
{
get
{
if (this.theItems == null)
{
this.theItems = new ObservableCollection<ItemEntity>();
}
return this.theItems;
}
set
{
this.theItems = value;
}
}
[DataMember]
public int TheCurrentIndex
{
get
{
return this.theCurrentIndex;
}
set
{
if (value != this.theCurrentIndex)
{
this.theCurrentIndex = value;
NotifyPropertyChanged("TheCurrentIndex");
NotifyPropertyChanged("IsSomeOtherPropertyEnabled");
}
}
}
这是 MainPage.xaml.cs 中的相关代码(App_ViewModelChanged 是在应用程序启动完成时执行的某些异步操作完成时调用的事件处理程序):
private void App_ViewModelChanged(object sender, ViewModelChangedEventArgs e)
{
BindToViewModel();
}
private void BindToViewModel()
{
this.DataContext = this.ViewModel;
this.ViewModel.IsViewEnabled = true;
}
private void SomeAsyncMethodCompleted(object sender, DetectCompletedEventArgs e)
{
if (e.Error == null)
{
this.ViewModel.TheCurrentIndex = e.Result;
}
}
这个问题不是一直在发生。大约 50% 的时间都会发生。它似乎在应用程序生命周期中只发生一次,然后就不会再发生了。此外,当我从 Silverlight Control Toolkit 的 2011 年 2 月版本切换到 2011 年 8 月版本时,该问题开始出现。以前从未遇到过这个问题。
这是一个已知问题吗?
I have a ListPicker in my Windows Phone 7 app where both the ItemsSource and SelectedIndex properties are bound to my ViewModel. SelectedIndex is using Two Way binding. The items and the SelectedIndex are correctly populated on application startup. However, when I modify the SelectedIndex property in my ViewModel the ListPicker's TextBox goes blank, as if there was no selected item. If I go to full mode and check which is the selected item from the list, the correct item is being selected.
Here is the ListPicker xaml code:
<toolkit:ListPicker Name="TheListPicker" ItemsSource="{Binding TheItems}" CacheMode="BitmapCache" FullModeHeader="{Binding Path=Resources.TheHeader, Source={StaticResource LocalizedStrings }}" SelectedIndex="{Binding TheCurrentIndex, Mode=TwoWay}" IsEnabled="{Binding IsViewEnabled}" TabIndex="0" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel x:Name="item" Orientation="Horizontal" Margin="5, 24, 0, 24">
<TextBlock Margin="15, 0, 0, 0" Text="{Binding Name}" FontSize="40" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
This is a simplified version of my ViewModel:
[DataMember]
public ObservableCollection<ItemEntity> TheItems
{
get
{
if (this.theItems == null)
{
this.theItems = new ObservableCollection<ItemEntity>();
}
return this.theItems;
}
set
{
this.theItems = value;
}
}
[DataMember]
public int TheCurrentIndex
{
get
{
return this.theCurrentIndex;
}
set
{
if (value != this.theCurrentIndex)
{
this.theCurrentIndex = value;
NotifyPropertyChanged("TheCurrentIndex");
NotifyPropertyChanged("IsSomeOtherPropertyEnabled");
}
}
}
And here is the relevant code from MainPage.xaml.cs (App_ViewModelChanged is an event handler invoked when some async stuff performed on application startup finishes):
private void App_ViewModelChanged(object sender, ViewModelChangedEventArgs e)
{
BindToViewModel();
}
private void BindToViewModel()
{
this.DataContext = this.ViewModel;
this.ViewModel.IsViewEnabled = true;
}
private void SomeAsyncMethodCompleted(object sender, DetectCompletedEventArgs e)
{
if (e.Error == null)
{
this.ViewModel.TheCurrentIndex = e.Result;
}
}
This issue is not happening all the time. Happens like 50% of the time. It seems to happen only once in the application lifetime and then never happens again. Also, the issue started appearing when I switched from the Feb 2011 release of the Silverlight Control Toolkit to the Aug 2011 release. Never had this issue before.
Is this a known issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,这种奇怪行为的原因是 2011 年 8 月 Silverlight 控件工具包中 ListPickerItem 样式的一个小变化。
这是 2011 年 8 月版本的外观:
这是 2011 年 2 月版本的外观:
看到区别了吗?他们在新版本中将 ListPickerItem Padding 更改为 8 10,这导致了问题。恢复到 8 6 可以解决这个问题。别问我为什么。
所以在我的项目中我实际上并没有修改控件工具包Generic.xaml文件,只是修改了具体的ListPicker资源来为ListPickerItem样式指定一个新的padding,就像这样:
这么小的改变!
Ok, so the reason for this strange behavior was a small change in the ListPickerItem style in Aug 2011 Silverlight Control Toolkit.
This is how it looks in Aug 2011 release:
And this is how it looked in Feb 2011 release:
See the difference? They changed the ListPickerItem Padding to 8 10 in the new release and somehow that was causing the issue. Reverting to 8 6 fixes it. Don't ask me why.
So in my project I didn't actually modified the control toolkit Generic.xaml file, but just modified the specific ListPicker resources to specify a new padding for the ListPickerItem style, like this:
Such a small change!