有没有办法获取显示给用户的第一个可见项目?
在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>
ViewModel
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,但是为了确定我的视图区域需要移动到哪里,我确实需要知道我的视图区域当前在哪里(顶部,中间,底部)
答案 0 :(得分:0)
对于我的问题(带有项目控件的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++;
}
}
答案 1 :(得分:-1)
您可以在集合标签中添加SelectedIndex="{Binding SelIndex}"
属性。
其中SelIndex将是ViewModel文件中与此属性绑定的属性。