Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF CollectionView/DataGrid获取第一个可见项的索引_C#_Wpf_Mvvm - Fatal编程技术网

C# WPF CollectionView/DataGrid获取第一个可见项的索引

C# WPF CollectionView/DataGrid获取第一个可见项的索引,c#,wpf,mvvm,C#,Wpf,Mvvm,是否有方法获取显示给用户的第一个可见项 在WinForms的DatagridView中,我们有FirstDisplayedScrollingRowIndex。 WPF变型是否有等效物 我在ViewModel中使用的CollectionView绑定到XAML中的数据网格 只是想澄清一下:I不想获取SelectedRow的索引,我 我已经可以做 示例 我的ObservableCollection中有20项,由于大小限制,我的Datagrid只能显示13项。 项目2之前由用户选择,之后用户向下滚动一点

是否有方法获取显示给用户的第一个可见项

在WinForms的
DatagridView
中,我们有
FirstDisplayedScrollingRowIndex
。 WPF变型是否有等效物

我在ViewModel中使用的CollectionView绑定到XAML中的数据网格

只是想澄清一下:I不想获取SelectedRow的索引,我 我已经可以做

示例
我的ObservableCollection中有20项,由于大小限制,我的Datagrid只能显示13项。 项目2之前由用户选择,之后用户向下滚动一点,因此项目5-17可见。 如何获取第5项的索引

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;
private observetecollection\u datagridColumns;
私人收藏视图_itemCollection;
private CollectionViewSource _itemCollectionSource;
公共ObservableCollection DatagridColumns
{
get=>\u datagridColumns;
设置
{
_datagridColumns=值;
RaisePropertyChanged();
}
}
公共集合查看项目集合
{
get=>\u itemCollection;
设置
{
_itemCollection=值;
RaisePropertyChanged();
}
}
公共集合视图源项集合源
{
get=>\u itemCollectionSource;
设置
{
_itemCollectionSource=值;
RaisePropertyChanged();
}
}
_datagridColumns=MainViewModel.GetColumns(MainViewModel.AppMode.Match);
_itemCollectionSource=新的CollectionViewSource();
ItemCollectionSource.Source=_vml.Main.ItemList;
_itemCollection=(CollectionView)ItemCollectionSource.View;
所需结果: 如果我的查看区域是…
-在顶部
我在顶部添加了一个项目(由于当前排序),我希望我的视图区域保持在顶部,这样我就可以看到我的新项目
-在底部我在底部添加了一个项目(由于当前排序),我希望我的视图区域移动到“新”底部,这样我就可以看到我的新项目
-在中间的任何地方,我想继续看同样的X项


我可以通过我的CollectionView访问SortOrder,但为了确定我的视图区域需要移动到哪里,我确实需要知道我的视图区域当前在哪里(顶部、中部、底部)

您可以在集合标记中添加
SelectedIndex=“{Binding SelIndex}”
属性

其中SelIndex将是ViewModel文件中绑定到此属性的属性。

对于我的问题(带有items控件的scrollviewer),我发现解决方案是捕获scroll changed事件并使用它。由于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">

如问题中所述:我不想要selectedRow的索引。我想获取第一个可见行的索引取决于您使用的是什么<代码>网格视图在
列表视图
数据网格
中?一些xaml会很有用。您想要可见元素有什么特别的原因吗?你可以使用的触发器总是有的。根据我想确定的当前可见区域,是否以及如何自动滚动。你到底想实现什么,使得了解此索引值成为必要?这并没有告诉我你的任何要求。你想滚动到那个项目,是因为它以某种方式连接到第一个项目,还是因为你只是想实现一些智能滚动(这会咬你)?它只是用来确定我的视图区域当前在哪里,这样我就可以决定我需要应用哪种类型的“智能滚动”
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++;
    }
}