ListBoxItem在OnSelectionChanged事件处理程序内的Trigger.Exit行为

时间:2015-09-25 11:52:36

标签: c# wpf mvvm

我有一个包含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中改变了选择吗?

2 个答案:

答案 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,它在我的环境中正常工作。虽然这不是我最初的问题的答案,但这是足够好的解决方法。