如何解决UWP组合框项目无缘无故地滚动到中间
我注意到在一个附加了某些项目源的组合框中,当没有选定的项目时,它倾向于滚动到项目的中间,而不是从顶部(第一个项目)开始,并且在选择一个项目时有时滚动到所选项目。
因此,我想在未选择任何项目时滚动到第一项。为此,我尝试了以下修复程序。
代码
private void ComboBoxKeyboardSelectionBehavior_DropDownopened(object sender,object e)
{
var comboBox = (ComboBox) sender;
if(comboBox.Selectedindex == -1)
{
//var scrollviewer = comboBox.GetScrollViewer();
//scrollviewer.ChangeView(0,null);
//var allItems = comboBox.Items.ToList();
//var cccc = comboBox.Items.Count;
//var firstItem = allItems.First();
var ci = comboBox.ContainerFromIndex(0) as ComboBoxItem;
if (ci != null)
{
ci.StartBringIntoView();
}
}
else
{
var ci = comboBox.ContainerFromIndex(comboBox.Selectedindex) as ComboBoxItem;
if (ci != null)
{
ci.StartBringIntoView();
}
}
}
WinRTXamlToolkit.Controls.Extensions 为我提供了获取scrollviewer的选项,然后尝试使用 ChangeView 方法,但该方法不起作用。我从列表中成功获取了第一项,并使用了 ContainerFromItem 方法,但它返回了null。因此,我还尝试了 ContainerFromIndex 方法,并将索引提供为 0 ,因为这应该是第一项,但还是可行的。
对于选中的项目(其他语句),它可以与ContainerFromIndex(comboBox.Selectedindex)
一起正常工作,但是只是为了测试我何时使用 ContainerFromItem 尝试它返回空值。
仅供参考,此事件是组合框样式的附属行为,但这无关紧要,因为行为对于所选项目场景而言是完美的。
解决方法
如果要在没有选定项目的情况下滚动到第一项,则需要更改DropDown
的{{1}}而不是{{ 1}}。
ComboBox
的{{1}}实际上是ScrollViewer
,显示ComboBox
的位置在后面的代码中已定义,我们无法访问对此。一种解决方法是找到DropDown
并在打开时重新放置它,但是使用此方法时,每次打开ComboBox
属性时我们都需要计算它,并且存在很多不同的值的方案Popup
。
因此,我们建议您自定义一个控件,该控件的行为类似于Popup
,并且在未选择任何项目的情况下将其定位到第一项。例如:
创建一个Popup
:
VerticalOffset
以及此UserControl中的代码:
VerticalOffset
您可以像下面这样在其他页面中使用ComboBox
:
UserControl
通过默认,此<Button x:Name="rootButton" BorderBrush="Gray" BorderThickness="2" Click="Button_Click" MinWidth="80" Background="Transparent" Padding="0">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Width="{Binding ElementName=rootButton,Path=ActualWidth}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="32" />
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind selectedItem,Mode=OneWay}" Grid.Column="0" VerticalAlignment="Center" FontSize="15" HorizontalAlignment="Center" />
<FontIcon Grid.Column="1" FontSize="12" FontFamily="Segoe MDL2 Assets" Glyph="" HorizontalAlignment="Right"
Margin="0,10,10" VerticalAlignment="Center" />
</Grid>
<FlyoutBase.AttachedFlyout>
<MenuFlyout Placement="Bottom" x:Name="menuFlyout">
<MenuFlyoutItem Text="Item 1" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 2" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 3" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 4" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 5" Click="MenuFlyoutItem_Click" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
将在其下面显示其public sealed partial class CustomComboBox : UserControl,INotifyPropertyChanged
{
public CustomComboBox()
{
this.InitializeComponent();
selectedItem = "";
}
private string _selectedItem;
public string selectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs("selectedItem"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void MenuFlyoutItem_Click(object sender,RoutedEventArgs e)
{
var item = sender as MenuFlyoutItem;
selectedItem = item.Text;
}
private void Button_Click(object sender,RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout(sender as Button);
}
}
列表。
此外,您还可以考虑使用其他控件(例如CustomComboBox
)直接替换<local:CustomComboBox VerticalAlignment="Center" HorizontalAlignment="Center" />
以避免这种情况。
更新:
当前,CustomComboBox
控件未提供用于在DropDown
中设置ListBox
的起始位置的相关API,但是我们有一种解决方法可以将ComboBox
放入其中ComboBox
,然后调用DropDown
方法来更改位置。例如:
- 定义从
Style
类继承的自定义组合框以获取ScrollViewer
:
DropDown
- 在
ChangeView
事件处理程序中使用ComboBox
初始化项目后,调用ScrollViewer
方法来更改位置:
public class TestComboBox : ComboBox
{
public ScrollViewer InternalScrollViewer;
protected override void OnApplyTemplate()
{
InternalScrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
base.OnApplyTemplate();
}
}
请注意,在 XAML 中使用ChangeView
代替Task.Delay()
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。