【问题标题】:Show dynamically elements of a ComboBox according to the scroll position根据滚动位置动态显示 ComboBox 的元素
【发布时间】:2017-03-27 03:21:13
【问题描述】:

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

我考虑过显示 ItemSource 中的前 20 个元素并将其余元素折叠起来,以便在滚动条到达底部时它们会变得可见,但我还没有成功。

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

我也在为这个 ComboBox 使用自定义样式

<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>

非常欢迎任何想法、建议或 cmets。 非常感谢!

【问题讨论】:

    标签: c# wpf xaml combobox


    【解决方案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。

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

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2019-09-06
      相关资源
      最近更新 更多