根据滚动位置动态显示ComboBox的元素

时间:2017-03-27 03:21:13

标签: c# wpf xaml combobox

我正在尝试制作一个ComboBox,根据滚动的位置动态显示其ItemSource中的元素,类似Facebook的新闻Feed,当您到达结尾时加载更多内容滚动查看器。

我想过显示ItemSource中的前20个元素,然后将其余元素折叠起来,这样当滚动条到达底部时它们会变得可见但我还没有成功。

这有可能实现吗?或者认为这可以做到太疯狂了?

此外,我正在使用这个ComboBox的cuztomized风格

<Style x:Key="CustomComboBox" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
    <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
    <Setter Property="IsEditable" Value="True"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="FontFamily" Value="Coves"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Border x:Name="TopBorder" 
                        CornerRadius="8"
                        BorderBrush="Grey"
                        BorderThickness="1"
                        Padding="10,0,1,0">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
                            <GradientStop Color="White" Offset="0"/>
                            <GradientStop Color="#e3e3e5" Offset="0.65"/>
                        </LinearGradientBrush>
                    </Border.Background>
                    <Grid>
                        <ToggleButton 
                        Name="ToggleButton" 
                        Template="{DynamicResource CustomComboBoxToggleButton}" 
                        Grid.Column="2" 
                        Focusable="false"
                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        ClickMode="Press">
                        </ToggleButton>
                        <TextBlock Name="ContentSite" IsHitTestVisible="False" 
                                      Text="{Binding Source={StaticResource Proxy}, Path=Data.Name, UpdateSourceTrigger=PropertyChanged}"
                                      Visibility="Visible" Foreground="#37465c"
                                      Padding="3,3,23,3" VerticalAlignment="Center"
                                      HorizontalAlignment="Left"/>
                        <Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True"
                                Focusable="False" PopupAnimation="Fade">
                            <StackPanel Orientation="Vertical" Width="215">
                                <Grid Name="DropDown" SnapsToDevicePixels="True"
                                    MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                    <Border x:Name="DropDownBorder" BorderThickness="1"
                                            BorderBrush="#888">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
                                                <GradientStop Color="White" Offset="0"/>
                                                <GradientStop Color="#e3e3e5" Offset="0.65"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <ScrollViewer Margin="0" SnapsToDevicePixels="True">
                                            <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
                                        </ScrollViewer>
                                    </Border>
                                </Grid>
                            </StackPanel>
                        </Popup>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Cursor" Value="Hand"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

非常欢迎任何想法,建议或意见。 非常感谢!

1 个答案:

答案 0 :(得分:1)

执行此操作的最简单方法可能是继承ComboBox并对其进行修改以创建PagingComboBox。下面你会找到一个小例子。不完美但有效。

<强> XAML的用法

 <PagingComboBox PagingSource="{Binding YourSource}" PageSize="15"/>

<强>控制

public class PagingComboBox : ComboBox {

    public PagingComboBox() {
      this.ItemsSource = new ObservableCollection<object>();
      this.Loaded += this.MyComboboxLoaded;
    }

    private int _currentItems = 0;
    private void MyComboboxLoaded(object sender, RoutedEventArgs e) {
      for (int i=0; i < this.PageSize; i++)
      {
        (this.ItemsSource as ObservableCollection<object>).Add(this.PagingSource[i]);
        this._currentItems++;
      }

      var sv = this.Template.FindName("DropDownScrollViewer", this) as ScrollViewer;
      sv.ScrollChanged += this.SvScrollChanged;

    }

    private void SvScrollChanged(object sender, ScrollChangedEventArgs e) {
      var sv = sender as ScrollViewer;
      var isAtEnd = sv.VerticalOffset == sv.ScrollableHeight;
      var cLimmit = this._currentItems + this.PageSize;
      if (isAtEnd && this._currentItems < this.PagingSource.Count) {
        for (int i = this._currentItems; i < cLimmit; i++)
        {
          if (i > this.PagingSource.Count - 1) return;
          (this.ItemsSource as ObservableCollection<object>).Add(this.PagingSource[i]);
          this._currentItems++;
        }
      }
    }

    public int PageSize {
      get {
        return (int)GetValue(PageSizeProperty);
      }
      set {
        SetValue(PageSizeProperty, value);
      }
    }

    // Using a DependencyProperty as the backing store for PageSize.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PageSizeProperty =
        DependencyProperty.Register("PageSize", typeof(int), typeof(PagingComboBox), new PropertyMetadata(20));



    public IList PagingSource {
      get {
        return (IList)GetValue(PagingSourceProperty);
      }
      set {
        SetValue(PagingSourceProperty, value);
      }
    }

    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PagingSourceProperty =
        DependencyProperty.Register("PagingSource", typeof(IList), typeof(PagingComboBox), new PropertyMetadata(null));



  }

注意

您可能必须为Scrollviewer命名(DropDownScrollViewer),因为您为它创建了一个自定义模板。一个缺点可能是丢失了Combobox的原始ItemsSource-Property。

希望这能为您提供如何实现此类功能的线索。