使用WPF和MVVM读取Outlook样式的空格键

时间:2011-06-24 17:49:48

标签: wpf mvvm

Microsoft Outlook的一个重要功能是其空格键阅读模式(打开阅读窗格)。假设您的收件箱中有5条消息,并显示第一条消息。显示的消息并不完全适合屏幕,因此当您按空格键时,就像在消息中向下翻页一样。您再次点击空格键,然后再次向下翻页。当您到达页面底部并再次按空格键时,它将转到下一条消息。

在WPF(使用MVVM模式构建应用程序)中执行此操作的好方法是什么?使用MVVM,我使用了一堆DataTemplates而不是usercontrols。

编辑:我应该提到我使用ListBox作为消息,使用FlowDocumentScrollViewer作为消息正文。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

对于后代,这是我对问题滚动部分的解决方案。此代码首先处理空间,然后,如果滚动条已经在底部,则它不处理KeyDown。 @ Hasan的推荐在那时推荐火灾。

internal class FlowDocumentScrollViewer2 : FlowDocumentScrollViewer
{
  private static bool PageDown<T>(T listView)
     where T : DependencyObject
  {
     var scrollViewer = GetVisualChild<ScrollViewer>(listView, null);
     var scrollBar = GetVisualChild<ScrollBar>(listView,
                                               bar => bar.Orientation == Orientation.Vertical);
     var formerOffset = scrollBar.Track.Value;
     scrollViewer.PageDown();
     scrollBar.Track.UpdateLayout();
     return formerOffset < scrollBar.Track.Value;
  }

  private static T GetVisualChild<T>(DependencyObject parent, Predicate<T> predicate)
     where T : Visual
  {
     T child = default(T);
     int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
     for (int i = 0; i < numVisuals; i++)
     {
        Visual v = (Visual) VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
           child = GetVisualChild(v, predicate);
        }
        if (child != null && (predicate == null || predicate(child)))
        {
           break;
        }
     }
     return child;
  }

  public FlowDocumentScrollViewer2()
  {
     PreviewKeyDown += PreviewSpaceDown;
  }

  private void PreviewSpaceDown(object sender, KeyEventArgs e)
  {
     if (e.Handled)
        return;
     if (e.Key == Key.Space)
     {
        e.Handled = PageDown(this);
     }
  }
}