[英]WPF CollectionView/DataGrid get index of first visible item
有沒有辦法獲取顯示給用戶的第一個可見項目?
在WinForms的DatagridView
我們具有FirstDisplayedScrollingRowIndex
。 WPF變體是否等效?
我在ViewModel中使用了CollectionView,該View綁定到XAML中的DataGrid。
只是要清楚:我不想讓SelectedRow的指數,這個我已經可以做...
例
我的ObservableCollection中有20個項目,由於大小限制,我的Datagrid僅顯示13個項目。 用戶先前選擇了Item2,然后用戶向下滾動了一點,因此可見項目5-17。 如何獲得item5的索引?
XAML
<Style x:Key="DatagridStyle" TargetType="DataGrid">
<Setter Property="AutoGenerateColumns" Value="False"/>
<Setter Property="Background" Value="{StaticResource ColorDatagridBackground}"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="CanUserDeleteRows" Value="False"/>
<Setter Property="CanUserResizeColumns" Value="False"/>
<Setter Property="CanUserReorderColumns" Value="True"/>
<Setter Property="CanUserSortColumns" Value="True"/>
<Setter Property="ColumnHeaderHeight" Value="25"/>
<Setter Property="Margin" Value="0,5,0,5"/>
<Setter Property="ItemsSource" Value="{Binding ItemCollection}"/>
</Style>
<DataGrid DockPanel.Dock="Top"
Style="{StaticResource DatagridStyle}"
util:DataGridColumnsBehavior.BindableColumns="{Binding DatagridColumns, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True"
EnableRowVirtualization="True">
<i:Interaction.Behaviors>
<util:DataGridScrollBehaviour />
</i:Interaction.Behaviors>
</DataGrid>
視圖模型
private ObservableCollection<DataGridColumn> _datagridColumns;
private CollectionView _itemCollection;
private CollectionViewSource _itemCollectionSource;
public ObservableCollection<DataGridColumn> DatagridColumns
{
get => _datagridColumns;
set
{
_datagridColumns = value;
RaisePropertyChanged();
}
}
public CollectionView ItemCollection
{
get => _itemCollection;
set
{
_itemCollection = value;
RaisePropertyChanged();
}
}
public CollectionViewSource ItemCollectionSource
{
get => _itemCollectionSource;
set
{
_itemCollectionSource = value;
RaisePropertyChanged();
}
}
_datagridColumns = MainViewModel.GetColumns(MainViewModel.AppMode.Match);
_itemCollectionSource = new CollectionViewSource();
ItemCollectionSource.Source = _vml.Main.ItemList;
_itemCollection = (CollectionView)ItemCollectionSource.View;
期望的結果:如果我的視野是...
-在頂部,並在頂部添加一個項目(由於當前排序),我希望我的視圖區域保持在頂部,這樣我就可以看到我的新項目
-在底部,並在底部添加一個項目(由於當前排序),我希望將視圖區域移至“新”底部,這樣我就可以看到我的新項目
-在中間的任何地方,我想繼續查看相同的X件商品
我可以通過CollectionView訪問SortOrder,但是為了確定我的視圖區域需要移動的位置,我確實需要知道我的視圖區域當前的位置(頂部,中間,底部)
對於我的問題(帶有項目控件的scrollviewer),我發現解決方案是捕獲滾動更改事件並使用它。 由於DataGrid具有滾動查看器,我認為您可以執行相同的操作,或者代替滾動更改,在最有意義的地方使用相同的邏輯。 因此,在后面的窗口代碼中:
private void dgScrollChanged(object sender, ScrollChangedEventArgs e)
{
int i = 0;
DataGrid dg = (DataGrid)sender;
foreach (ObservableFlatObservations o in dg.Items)
{
UIElement v = (UIElement)dg.ItemContainerGenerator.ContainerFromItem(o);
GeneralTransform childTransform = v.TransformToAncestor((ScrollViewer)sender);
Rect rectangle = childTransform.TransformBounds(new Rect(new Point(0, 0), v.RenderSize));
Rect result = Rect.Intersect(new Rect(new Point(0, 0), ((ScrollViewer)sender).RenderSize), rectangle);
if (result != Rect.Empty)
{
//This one is visible so do some stuff
return;// i is the index of this item
}
i++;
}
}
在datagrid xaml定義中:
<DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch"
ItemsSource="{Binding oFObs.View}"
SelectedItem="{Binding CurrentObs, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
IsReadOnly="True"
Grid.Row="1" Grid.ColumnSpan="3"
ScrollViewer.ScrollChanged="dgScrollChanged">
我尚未使用datagrid對此進行過測試,但是這種方法在我的原始案例中效果很好。 請注意,我的數據元素名稱未映射到您的問題,但是我認為您可以對其進行修改以使用您所擁有的名稱。
經過實際嘗試,事實證明可能更簡單。 在事件處理程序中,只有網格中可見的行才會從ContainerFromItem調用返回值,因為datagrid會虛擬化內容。 因此,我認為如果您執行以下操作,則可以在數據網格中找到第一個可見索引:
private void dgScrollChanged(object sender, ScrollChangedEventArgs e)
{
int i = 0;
DataGrid dg = (DataGrid)sender;
foreach (GetFlatObservationsResult o in dg.ItemsSource)
{
DataGridRow v = (DataGridRow)dg.ItemContainerGenerator.ContainerFromItem(o);
if(v!=null)
{
//i is the index of the first visable row
//do some stuff
return;
}
i++;
}
}
您可以在集合標記中添加SelectedIndex="{Binding SelIndex}"
屬性。
其中SelIndex將是ViewModel文件中與此屬性綁定的屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.