如何将选定的行移到DataGrid的可见区域? (MVVM)

时间:2019-05-19 12:49:57

标签: wpf mvvm datagrid focus

这是我的情况。

我有一个包含许多项目的DataGrid。

    <DataGrid Grid.Row="2"

            ItemsSource="{Binding Dati, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
            SelectedItem="{Binding SelectRowGrid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
            Style="{DynamicResource ST_DataGrid}" 
            CellStyle="{DynamicResource St_DataGridCellStyle}" SelectionMode="Single"
            Grid.Column="1" Grid.RowSpan="2">

   <DataGrid.Columns>

搜索成功后,我想移至DataGrid中的行。

我该怎么做?非常感谢。

这是SelectRowGrid属性

Public Property Dati As ObservableCollection(Of Model_Database)

Private _SelectRowGrid As Model_Database
Public Property SelectRowGrid As Model_Database
    Get
        Return _SelectRowGrid
    End Get
    Set(value As Model_Database)
        _SelectRowGrid = value
        OnPropertyChanged("SelectRowGrid")
    End Set
End Property

这是搜索代码

    Private _TxtSearch As String
    Public Property TxtSearch As String
    Get
        Return _TxtSearch
    End Get
    Set(value As String)
        _TxtSearch = value
        OnPropertyChanged("TxtSearch")

        SelectRowGrid = (From n In Me.Dati Where n.c_amb.ToUpper().Trim Like _TxtSearch.ToUpper().Trim() + "*" Select n).FirstOrDefault()

       'Now I want position on the Datagrid row 

    End Set
End Property

换句话说,我需要这个,将焦点移到datagrid中等于 Mary 的行上。 看图片。 非常感谢

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

我为此使用了2段代码。 C#,但您应该能够通过在线转换器运行它。 一个将选定的行显示到视图中,另一个将其聚焦。

我忘记了它们的确切来源-我已经使用了一段时间了。

    class ScrollDataGridRowIntoView : Behavior<DataGrid>
    {
        protected override void OnAttached()
        {

            base.OnAttached();
            this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
        }
        void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender is DataGrid)
            {
                DataGrid datagrid = (sender as DataGrid);
                if (datagrid.SelectedItem != null)
                {
                    datagrid.Dispatcher.BeginInvoke((Action)(() =>
                    {
                        datagrid.UpdateLayout();
                        if (datagrid.SelectedItem != null)
                        {
                            datagrid.ScrollIntoView(datagrid.SelectedItem);
                        }
                    }));
                }
            }
        }
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
        }
    }

    class DataGridRowFocusBehavior : Behavior<DataGridRow>
    {
        public static bool GetIsDataGridRowFocussedWhenSelected(DataGridRow dataGridRow)
        {
            return (bool)dataGridRow.GetValue(IsDataGridRowFocussedWhenSelectedProperty);
        }

        public static void SetIsDataGridRowFocussedWhenSelected(
          DataGridRow dataGridRow, bool value)
        {
            dataGridRow.SetValue(IsDataGridRowFocussedWhenSelectedProperty, value);
        }

        public static readonly DependencyProperty IsDataGridRowFocussedWhenSelectedProperty =
            DependencyProperty.RegisterAttached(
            "IsDataGridRowFocussedWhenSelected",
            typeof(bool),
            typeof(DataGridRowFocusBehavior),
            new UIPropertyMetadata(false, OnIsDataGridRowFocussedWhenSelectedChanged));

        static void OnIsDataGridRowFocussedWhenSelectedChanged(
          DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            DataGridRow item = depObj as DataGridRow;
            if (item == null)
                return;

            if (e.NewValue is bool == false)
                return;

            if ((bool)e.NewValue)
                item.Selected += OndataGridRowSelected;
            else
                item.Selected -= OndataGridRowSelected;
        }
        static void OndataGridRowSelected(object sender, RoutedEventArgs e)
        {
            DataGridRow row = e.OriginalSource as DataGridRow;
            // If focus is already on a cell then don't focus back out of it
            if (!(Keyboard.FocusedElement is DataGridCell) && row != null)
            {
                row.Focusable = true;
                Keyboard.Focus(row);
            }
        }
    }

在我的数据网格中:

        <i:Interaction.Behaviors>
            <local:ScrollDataGridRowIntoView />
        </i:Interaction.Behaviors>
        <DataGrid.RowStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="local:DataGridRowBehavior.IsDataGridRowFocussedWhenSelected" Value="true"/>
            </Style>
        </DataGrid.RowStyle>

i的xmlns:

         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"