我在 WPF 中使用 ListBox 控件来显示某些内容,并且此 ListBox 中的每个项目都有相同的高度,当我拖动滚动条时,我如何知道哪个项目位于当前 ListBox 视图的顶部?谢谢你。
问问题
436 次
2 回答
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
于 2012-11-29T04:40:25.767 回答
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;
}
于 2012-11-29T04:54:35.590 回答