我在WPF中使用ListBox控件来显示内容,并且此ListBox中的每个项目具有相同的高度,当我拖动滚动条时,如何知道当前ListBox视图顶部的哪个项目?谢谢。
答案 0 :(得分:1)
<Grid DataContext="{Binding ElementName=This}">
<StackPanel>
<ListBox Height="100" ScrollViewer.ScrollChanged="ListBox_ScrollChanged">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>4</ListBoxItem>
<ListBoxItem>5</ListBoxItem>
<ListBoxItem>6</ListBoxItem>
<ListBoxItem>7</ListBoxItem>
<ListBoxItem>8</ListBoxItem>
<ListBoxItem>9</ListBoxItem>
<ListBoxItem>10</ListBoxItem>
<ListBoxItem>11</ListBoxItem>
<ListBoxItem>12</ListBoxItem>
<ListBoxItem>13</ListBoxItem>
<ListBoxItem>14</ListBoxItem>
<ListBoxItem>15</ListBoxItem>
<ListBoxItem>16</ListBoxItem>
<ListBoxItem>17</ListBoxItem>
<ListBoxItem>18</ListBoxItem>
</ListBox>
<TextBlock Text="{Binding TopMostItem}"/>
</StackPanel>
</Grid>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
private String _topMost;
public String TopMostItem
{
get { return _topMost; }
set { _topMost = value; RaisePropertyChanged("TopMostItem"); }
}
private void ListBox_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
var lb = sender as ListBox;
foreach (var lbi in lb.Items)
{
var container = lb.ItemContainerGenerator.ContainerFromItem(lbi) as ListBoxItem;
if (container != null && IsUserVisible(container, lb))
{
TopMostItem = container.Content as String;
return;
}
}
}
private bool IsUserVisible(FrameworkElement element, FrameworkElement container)
{
if (!element.IsVisible)
return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
Rect fudgybounds = new Rect(new Point(bounds.TopLeft.X, bounds.TopLeft.Y), new Point(bounds.BottomRight.X, bounds.BottomRight.Y - 5));
return rect.Contains(fudgybounds.TopLeft) || rect.Contains(fudgybounds.BottomRight);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(name));
}
#endregion
IsUserVisible方法礼貌: Find WPF Controls in Viewport
答案 1 :(得分:0)
您可以使用此代码:
public static FrameworkElement GetFirstItem(ListBox listBox)
{
if (listBox.Items.Count == 0)
return null;
VirtualizingStackPanel vsp = VisualTreeHelper.GetParent(listBox.Items[0] as FrameworkElement) as VirtualizingStackPanel;
if (vsp != null)
{
int fvi = (int)vsp.VerticalOffset;
int vic = (int)vsp.ViewportHeight;
int index=-1;
foreach (FrameworkElement item in listBox.Items)
{
index++;
if (index >= fvi && index <= fvi + vic)
{
return item;
}
}
}
return null;
}