2

我们正在尝试使用 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"));
        }
    }
}

托管组合框的 XAML 用户控件

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

滚动位置一

滚动位置二

4

2 回答 2

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;
            }
        }
    }
于 2013-10-06T23:50:12.330 回答
-1
<Combobox ScrollViewer.CanContentScroll="False"></Combobox>

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

问候, 拉蒂坎塔

于 2016-09-28T18:14:46.267 回答