2

ICollectionView を使用して、ComboBox 内の項目の単純なグループ化を実装しようとしています。CollectionView で使用されているグループ化と並べ替えは正しく機能します。ただし、スクロール バーはアイテムではなくグループをスクロールするため、ComboBox によって作成されたポップアップ アイテム リストは意図したとおりに機能しません。

例: 25 アイテムのグループが 2 つある場合、スクロール バーには、目的の 50 ではなく、スクロールする 2 つの位置/ポイントがあります。

スクロールバーがグループ内のアイテムではなくグループをスクロールする理由と、この動作をどのように変更できるかを誰か説明できますか?

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>

スクロール位置 1

スクロール位置 2

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 に答える