【问题标题】:Navigation in WPF datagridWPF 数据网格中的导航
【发布时间】:2014-07-04 20:33:32
【问题描述】:

我有一个数据网格,我希望我的 Enter 键像 TAB 键一样工作。所以,我关注了this 的帖子。

按照该帖子接受的答案后,我获得了所需的功能。但是我遇到了一个小问题。

当我在 DataGrid 的最后一行的最后一个单元格上按 Enter 时,会在数据网格中添加一个新行,但新添加行的最后一个单元格会聚焦于第一个单元格而不是第一个单元格。

我想要的是当我在最后一行的最后一个单元格上按 enter 时,应该添加一个新行,并且应该关注新创建行的第一个单元格而不是最后一个单元格。

注意:仅当向数据网格添加新行时才会出现上述问题。在浏览现有行时,它按预期工作。

在这个示例项目中我主要使用了 4 个文件。

Person.cs

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
}

MainWindowViewModel.cs

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        People = new ObservableCollection<Person>();
    }

    private ObservableCollection<Person> _people;
    public ObservableCollection<Person> People
    {
        get
        {
            return _people;
        }
        set
        {
            _people = value;
            OnPropertyChanged("People");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

        <DataGrid x:Name="maindg" AutoGenerateColumns="True" 
                  ItemsSource="{Binding People}" 
                  PreviewKeyDown="DataGrid_KeyDown_1" SelectedIndex="0"   
                  GridLinesVisibility="Vertical" 
                  SelectionMode="Single" SelectionUnit="CellOrRowHeader">

        </DataGrid>

</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void DataGrid_KeyDown_1(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Enter) return;

        DependencyObject dep = (DependencyObject)e.OriginalSource;
        //here we just find the cell got focused ...
        //then we can use the cell key down or key up
        // iteratively traverse the visual tree
        while ((dep != null) && !(dep is DataGridCell) && !(dep is DataGridColumnHeader))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        if (dep == null)
            return;

        if (dep is DataGridCell)
        {
            //cancel if datagrid in edit mode
            maindg.CommitEdit();
            //get current cell
            DataGridCell cell = dep as DataGridCell;
            //deselect current cell
            cell.IsSelected = false;
            //find next right cell
            var nextCell = cell.PredictFocus(FocusNavigationDirection.Right);
            //if next right cell null go for find next ro first cell
            if (nextCell == null)
            {
                DependencyObject nextRowCell;
                nextRowCell = cell.PredictFocus(FocusNavigationDirection.Down);
                //if next row is null so we have no more row Return;
                if (nextRowCell == null) return;
                //we do this because we cant use FocusNavigationDirection.Next for function PredictFocus
                //so we have to find it this way
                while ((nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left) != null)
                    nextRowCell = (nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left);
                //set new cell as next cell
                nextCell = nextRowCell;
            }

            //change current cell
            maindg.CurrentCell = new DataGridCellInfo(nextCell as DataGridCell);
            //change selected cell
            (nextCell as DataGridCell).IsSelected = true;
            // start edit mode
            maindg.BeginEdit();
        }
        //handl the default action of keydown
        e.Handled = true;
    }
}

为了简单起见,我没有发布样式代码。

【问题讨论】:

  • 漂亮的图片。发布您已经尝试过的相关代码和 XAML。
  • 我已经按照你的建议发布了代码。

标签: c# wpf datagrid focus


【解决方案1】:

在 DataGrid_KeyDown_1 事件处理程序中替换这行代码

if (nextRowCell == null) return;

有了这个:

if (nextRowCell == null)
{
    nextRowCell = dep;
    while ((nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left) != null)
    nextRowCell = (nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left);
    //change current cell
    maindg.CurrentCell = new DataGridCellInfo(nextRowCell as DataGridCell);
    //change selected cell
    (nextRowCell as DataGridCell).IsSelected = true;
    return;
} 

【讨论】:

    猜你喜欢
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多