我有一个包含5个项目(年)的ListBox。当用户选择最后一项时,我希望将ListBox项目向前移动一年,但保持对用户点击年份的选择:
2011 2012 2013 2014 2015 应转向2012 2013 2014 2015 2016。
我通过搞乱底层的ViewModel来做到这一点:
private void Calendar_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_calendarUpdateInProgress) return;
_calendarUpdateInProgress = true;
var cvm = YearsListBox.SelectedItem as CalendarElementViewModel;
if (cvm != null)
{
int year = cvm.Year; //year I would like to keep selected
VM.ShiftYear(year); //change year properties of viewmodels in ItemsSource
YearsListBox.UnselectAll();
foreach (CalendarElementViewModel item in YearsListBox.Items)
{
if (item.Year == year)
{
YearsListBox.SelectedItem = item;
break;
}
}
}
}
我现在得到的是2012 2013 2014 2015 2016 ,似乎这个ListBoxItem样式触发器不会取消选择:
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnSelected}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnSelected}" />
</Trigger.ExitActions>
</Trigger>
如预期的那样,YearsListBox有一个实际选定的项目(2015)。我试图跟踪ListBoxItem Selected和Unselected事件 - 它们也以正确的顺序触发。当我尝试更改非边框项目之间的选择时,会正确取消选择它们。 这里发生了什么以及为什么最后一项没有正确更新?是因为我已经在OnSelectionChanged中改变了选择吗?
答案 0 :(得分:0)
更改视图模型的值会使您需要移动选择的内容变得复杂,这也会再次触发选择。
尝试这样的事情:
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox.SelectedIndex == this.YearListBox.Count - 1)
{
this.YearListBox.Add(new CalendarElementViewModel() { Year = this.YearListBox.Last().Year + 1 });
this.YearListBox.RemoveAt(0);
}
}
此外,您可以使用listboxitems的visibility属性来隐藏年份。
答案 1 :(得分:0)
在处理最小代码示例时,我注意到默认样式的ListBoxItem不会出现这种行为。区别在于处理选择状态 - 我通过Actor.ask
使用它的样式,它的Trigger.ExitAction就不会触发。
默认ListBoxItem使用VisualStateManager,它在我的环境中正常工作。虽然这不是我最初的问题的答案,但这是足够好的解决方法。