WPF分组组合框滚动组不是项目

时间:2013-07-10 05:02:25

标签: wpf combobox scrollbar collectionview

我们正尝试使用ICollectionView在ComboBox中实现简单的项目分组。 CollectionView中使用的分组和排序正常工作。但是ComboBox创建的弹出项目列表无法按预期运行,因为滚动条会滚动组而不是项目。

例如:如果有2组25个项目,那么滚动条将有两个位置/点来滚动而不是所需的50个。

有人可以解释为什么滚动条会滚动组而不是组中的项目,以及我们如何更改此行为?

Viewmodel设置 ICollectionView

public ViewModel()
{

CurrenciesView.Filter = CurrencyFilter;
CurrenciesView.SortDescriptions.Add(new SortDescription("MajorCurrency", ListSortDirection.Descending));
CurrenciesView.SortDescriptions.Add(new SortDescription("Code", ListSortDirection.Ascending));
CurrenciesView.GroupDescriptions.Add(new PropertyGroupDescription("MajorCurrency", new CurrencyGroupConverter()));


public ICollectionView CurrenciesView { get { return CollectionViewSource.GetDefaultView(currencies); } }
    private ObservableCollection<Currency> currencies = new ObservableCollection<Currency>();
public ObservableCollection<Currency> Currencies
{
    get { return this.currencies; }
    set
    {
        if (this.currencies != value)
        {
            this.currencies = value;
            this.PropertyChanged(this, new PropertyChangedEventArgs("Currencies"));
        }
    }
}

托管ComboBox的XAML UserControl

<UserControl x:Class="FilterView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:vm="clr-namespace:ViewModels">
<UserControl.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="CurrencyItem">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Code}" FontWeight="ExtraBold"/>
                <TextBlock Text="{Binding Description}" Margin="10,0,0,0"/>
            </StackPanel>
        </DataTemplate>
        <Style TargetType="ComboBox">
            <Setter Property="MinWidth" Value="100"/>
            <Setter Property="Margin" Value="0,5,0,5"/>
        </Style>
        <DataTemplate x:Key="GroupHeader">
            <TextBlock Text="{Binding Name}" Padding="3"/>
        </DataTemplate>
    </ResourceDictionary>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Column="0" Grid.Row="0">Currency</Label>
    <ComboBox Grid.Column="1" Grid.Row="0" Name="Currency"
                        ItemsSource="{Binding Path=CurrenciesView, Mode=OneWay}"
                        ItemTemplate="{StaticResource CurrencyItem}"
                        SelectedValuePath="Code"
                        IsSynchronizedWithCurrentItem="True">
        <ComboBox.GroupStyle>
            <GroupStyle HeaderTemplate="{StaticResource GroupHeader}"/>
        </ComboBox.GroupStyle>
    </ComboBox>
</Grid>
</UserControl>

Scroll Position One

Scroll Position Two

2 个答案:

答案 0 :(得分:5)

通过在子项ScrollViewer的PART_Popup模板上设置CanContentScroll = false来解决。

<UserControl x:Class="FilterView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:ViewModels">
  <UserControl.Resources>
    <ResourceDictionary>
      <DataTemplate x:Key="CurrencyItem">
        <StackPanel Orientation="Horizontal">
          <TextBlock Text="{Binding Code}" FontWeight="ExtraBold"/>
          <TextBlock Text="{Binding Description}" Margin="10,0,0,0"/>
        </StackPanel>
      </DataTemplate>
      <Style TargetType="ComboBox">
        <Setter Property="MinWidth" Value="100"/>
        <Setter Property="Margin" Value="0,5,0,5"/>
      </Style>
      <DataTemplate x:Key="GroupHeader">
        <TextBlock Text="{Binding Name}" Padding="3"/>
      </DataTemplate>
    </ResourceDictionary>
  </UserControl.Resources>
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Column="0" Grid.Row="0">Currency</Label>
    <ComboBox Grid.Column="1" Grid.Row="0" Name="Currency"
              ItemsSource="{Binding Path=CurrenciesView, Mode=OneWay}"
              ItemTemplate="{StaticResource CurrencyItem}"
              SelectedValuePath="Code"
              IsSynchronizedWithCurrentItem="True"
              **ScrollViewer.HorizontalScrollBarVisibility="Auto"
              ScrollViewer.VerticalScrollBarVisibility="Auto"
              ScrollViewer.CanContentScroll="True"**>
      <ComboBox.GroupStyle>
        <GroupStyle HeaderTemplate="{StaticResource GroupHeader}"/>
      </ComboBox.GroupStyle>
    </ComboBox>
  </Grid>
</UserControl>

或者在ComboBox派生控件中:

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Popup popup = GetTemplateChild("PART_Popup") as Popup;
        if (popup != null)
        {
            ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(popup.Child);
            if (scrollViewer != null)
            {
                scrollViewer.CanContentScroll = false;
            }
        }
    }

答案 1 :(得分:-2)

<Combobox ScrollViewer.CanContentScroll="False"></Combobox>

使用上面的代码可以解决问题。

此致 Ratikanta