ListBoxItem触发器.OnSelectionChanged事件处理程序中的退出行为
本文关键字:退出 程序 触发器 OnSelectionChanged 事件处理 ListBoxItem | 更新日期: 2023-09-27 18:14:35
我有一个包含5个项目(年份)的ListBox。当用户选择最后一项时,我想将列表框项向前移动一年,但保留用户单击的年份的选择:
2011 2012 2013 2014 2015应转为2012 2013 2014 2015 2016。
我是通过搞乱底层ViewModels来做到这一点的:
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 20152016,似乎这个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?
改变视图模型的值使事情变得复杂,它需要你移动你的选择,这也会触发选择再次改变。
试试这样写:
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);
}
}
也可以使用列表框项的可见性属性来隐藏年份
在编写最小代码示例时,我注意到默认样式的ListBoxItem不会表现出这样的行为。不同之处在于处理选择状态的方式,我使用的方式是通过<Trigger Property="IsSelected">
和它的触发器。ExitAction不会触发
默认ListBoxItem使用VisualStateManager,它在我的情况下正确工作。虽然这不是我最初问题的答案,但它是一个足够好的变通方法。