【问题标题】:WPF DataGrid changing row selection to a cell's TextBoxWPF DataGrid 将行选择更改为单元格的文本框
【发布时间】:2014-07-14 20:33:30
【问题描述】:

我有一个 DataGrid,当用户点击向下箭头时,它需要移动到下面的下一行,但关注一个包含文本框的单元格。我不想关注文本框而不是实际的单元格。这就是我的 DataGrid 的样子;

<DataGrid Name="myDataGrid" PreviewKeyDown="myDataGrid_PreviewKeyDown">
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Description" IsReadOnly="True" Width="Auto">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                    <TextBlock HorizontalAlignment="Right" Text="{Binding Path=Descrip, Mode=TwoWay, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged, StringFormat=C, ConverterCulture=en-us}" TextAlignment="Right"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTemplateColumn Header="Units Counted" Width="Auto">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox BorderBrush="Black" BorderThickness="2" FontWeight="Bold" Margin="2" Text="{Binding Path=UnitCounted, Mode=TwoWay, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextAlignment="Right" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

private void myDataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Down)
        {
            e.Handled = true;
            int indx = myDataGrid.SelectedIndex + 1;
            myDataGrid.SelectedIndex = indx;
            myDataGrid.CurrentCell = new DataGridCellInfo(myDataGrid.Items[indx], myDataGrid.Columns[1])
        }
    }

这样做会选择单元格而不是文本框。如果我将此添加到文本框;

FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"

它将光标添加到每一行文本框,但不关注文本框。

谢谢

编辑:感谢@Sheridan,我更接近这段代码;

<TextBox 
BorderBrush="Black" 
BorderThickness="2" 
FontWeight="Bold" 
Margin="2" 
Text="{Binding Path=UnitCounted, Mode=TwoWay, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
TextAlignment="Right" 
FocusManager.IsFocusScope="True"
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>

然后在我的myDataGrid_PreviewKeyDown 中添加myDataGrid.BeginEdit() 允许它工作。问题是 BeginEdit 似乎永远不会真正结束。我该如何解决这个问题?

【问题讨论】:

  • 我建议你阅读 MSDN 上的Focus Overview 页面。 它将光标添加到每一行文本框,但不关注文本框。 设置FocusManager.FocusedElement 属性会将逻辑焦点设置为在其焦点内的元素范围...所以他们专注的,但只是在他们的专注范围内。请阅读链接页面,了解如何管理您的专注要求。
  • 请看上面的编辑

标签: c# wpf datagrid textbox


【解决方案1】:

我不会与FocusManager.FocusedElement 混淆,因为您会得到未知的警告,它可以像您现在使用BeginEdit 所经历的那样。

我在 TextBox 上所做的工作很简单,在 xaml 中

<DataGrid Name="myDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Loans}" PreviewKeyDown="UIElement_OnPreviewMouseDown">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Units Counted" Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox x:Name="sampleTextBox" HorizontalAlignment="Right" Text="{Binding Name}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

在类文件中我有

    public static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

    private void UIElement_OnPreviewMouseDown(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Down) return;
        e.Handled = true;
        var indx = myDataGrid.SelectedIndex + 1;
        myDataGrid.SelectedIndex = indx;
        myDataGrid.CurrentCell = new DataGridCellInfo(myDataGrid.Items[indx], myDataGrid.Columns[0]);

        var row = this.myDataGrid.ItemContainerGenerator.ContainerFromItem(myDataGrid.CurrentCell.Item) as DataGridRow;
        var presenter = GetVisualChild<DataGridCellsPresenter>(row);


        var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromItem(myDataGrid.CurrentCell.Item);
        if (cell != null)
        {
            var contentPresenter = cell.Content as ContentPresenter;
            if (contentPresenter != null)
            {
                var m = contentPresenter.ContentTemplate.FindName("sampleTextBox", contentPresenter);
                ((TextBox) m).Focus();
            }
        }
    }
}

现在,当每次按下Down 键并更改单元格选择时,这将使TextBox 成为焦点。

【讨论】:

    猜你喜欢
    • 2017-08-07
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2015-11-19
    • 2018-04-29
    • 1970-01-01
    相关资源
    最近更新 更多