2013-04-10 55 views
0

我有一个ListView控件,支持增量加载大型项目集合。当用户向下滚动到底部ListView的垂直滚动条时,触发附加项的加载。我努力在实现中使用MVVM模式(没有代码隐藏),但恕我直言,在这种特殊情况下,它不是必需的。从WPF控件提高用户定义的事件

我在介绍一个新事件(例如NeedsMoreItems)和可能的子类ListView(ListViewWithIncrementalLoading),以便应用程序不需要执行ScrollChanged事件映射。我之前没有为XAML控件实现自定义事件,所以我不太确定实现这一点的最简单方法。我是否需要创建自定义控件?用户控制?使用附加事件?

如果你有类似任务的代码片段,我会非常感激。

+0

在这里不能真正添加​​任何东西到这个问题,这是广泛的在我看来。但是,还是普遍认为“好”MVVM不惜代价避免代码?在许多情况下,代码隐藏是无法避免的,而你不应该这样做。你应该做的是从业务逻辑和设计中分离UI逻辑,这就是MVVM的全部原因。 – dowhilefor 2013-04-10 16:02:06

+0

我更新了我的帖子,补充说下面的MVVM模式在这种情况下可能不是必需的。我们不关注MVVM,更多的是关于如何使用用户定义的事件来扩展控件。 – 2013-04-10 16:43:38

回答

1

这不是完整的代码,因为这是非常困难的开发,它是非常多的代码(在软件CCFinder中使用),也不是完美的,但它是它的工作。

<CCFinder:AnimatedScrollViewer VerticalScrollBarVisibility="{Binding IsItemsFound, Converter={StaticResource __boolToVisibilityConverter}}" Margin="36,211,38,72" 
        ScrollChanged="ScrollViewer_ScrollChanged" HorizontalContentAlignment="Center" Focusable="False" x:Name="ScrolView1"> 

      <ItemsControl Name="_itemsControl" ItemsSource="{Binding CurrentImages}" 
      ... 

在代码隐藏:

private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) 
    { 
     if (e.VerticalOffset + e.ViewportHeight == e.ExtentHeight) 
     { 
      var scroller = ((ScrollViewer)sender); 
      scroller.ReleaseMouseCapture(); 
      scroller.InvalidateScrollInfo(); 
      ((OverviewViewModel)this.DataContext).ShowMoreTriggered(); 
     } 
    } 

所以来这里的重要组成部分:在视图模型I类设置MaximumImages属性更高的价值......它始于50,然后升起当再次触发时为251,然后为500。在MaximumImages的setter中,WPF框架被通知CurrentImages已经改变,并且在CurrentImages获取器中,我有很多笨重的代码,它们意识到MaximumImages数字现在比以前更高,并且将新项目添加到CurrentImages(全部吸气剂)。不要太漂亮,但它的工作原理,并大多在ViewModel类:

public void ShowMoreTriggered() 
    { 
     if (Photos != null && !ShowMoreTriggeredActive && MaximumImages < Photos.Count) 
     { 
      ShowMoreTriggeredActive = true; 
      ThreadPool.QueueUserWorkItem(delegate 
              { 
               Thread.Sleep(1000); 
               MaximumImages = MaximumImages < 251 ? 251 : 500; 
               Thread.Sleep(1500); 
               ShowMoreTriggeredActive = false; 
              }); 
     } 
    } 

    private int _maximumImages; 
    public int MaximumImages 
    { 
     get 
     { 
      return _maximumImages; 
     } 
     set 
     { 
      _maximumImages = value; 
      InvokePropertyChanged("MaximumImages"); 
      InvokePropertyChanged("CurrentImages"); 
     } 
    } 

当然,这将是更优雅的提高的情况下,滚动事件到达最低点时,用户定义的事件,但我想它只会生成更多的代码,而不会更少,因为无论如何它肯定会从ScrollChanged事件传播。

+0

非常感谢您的回复,感谢您的回复。这是一个很好的提示,但是我会努力找到一个更可重用的解决方案,这样我就可以通过定义一个自定义甚至(仍然需要弄清楚如何去做)或子类化控件来封装这个行为。 – 2013-04-17 19:11:07

+0

如果你找到解决方案,我会很高兴知道这一点。 :-) – Akku 2013-04-18 10:06:54