我们正尝试使用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>
答案 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