无法选择 WPF 数据网格中的第一行
本文关键字:一行 选择 WPF 数据 网格 数据网 | 更新日期: 2023-09-27 18:33:42
我有一个 WPF 数据网格,其中有 3 列作为窗口的一部分。ItemsSource 是从一组付款对象 (grdPayments.ItemsSource = payments ) 设置的。 当焦点设置为后面代码中的网格时,我希望第一行中的第三个单元格获得焦点。
无论我使用以下哪种方法,都会选择并聚焦第二行而不是第一行。
这会将焦点设置为第 2 行中的第 3 个单元格:
grdPayments.Focus();
grdPayments.CurrentCell = new DataGridCellInfo(grdPayments.Items[0],grdPayments.Columns[2]);
grdPayments.SelectedCells.Add(dataGridCellInfo);
cell.Focus();
grdPayments.BeginEdit();
这会将焦点设置为第二行:
grdPayments.Focus();
grdPayments.SelectedIndex = 0;
grdPayments.BeginEdit();
谁能告诉我发生了什么? DataGrid XAML 如下所示。my:NumberEntry 是一个自定义控件:
<DataGrid Name="grdPayments"
AutoGenerateColumns="False"
Background="#FF21B721"
ItemsSource="{Binding}"
SelectionUnit="Cell"
SelectionMode="Single"
Margin="5"
VirtualizingPanel.IsVirtualizing="False">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#FF21B721"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Width="240"
Binding="{Binding Path=Description}"
Header="Description"
IsReadOnly="True"
TextBlock.TextAlignment="Center">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{StaticResource clBr}"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTemplateColumn Width="100" Header="Due">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="100" Text="{Binding Path=Due, Converter={StaticResource CurrencyPadder}, ConverterParameter=10}" Background="{StaticResource clBr}" Focusable="False"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="100" Header="Paid">
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{StaticResource clBr}"/>
</Style>
</DataGridTemplateColumn.CellStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<my:NumberEntry Decimals="2"
LostFocus="NumberEditor_LostFocus"
PreviewKeyDown="NumberEditor_PreviewKeyDown"
MaxLength="10"
TextAlignment="Right"
Text="{Binding Path=Paid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
我 99% 确定您需要删除:
SelectionUnit="Cell"
要访问SelectionUnit
设置为 Cell
的行,您必须执行以下操作:
grdPayments.SelectedItem = grdPayments.SelectedCells[0].item;
仅当您一次只能选择一个单元格(不在扩展模式下)时,它才有效。
使 WPF 数据网格按照我希望的方式运行似乎是一个失败的原因:它只是没有设计为根据我的需求运行。
相反,我所做的是在代码隐藏中动态构建一个单元格网格。 一行中的每个单元格都可以进行精细设计,以执行我想要的任何操作。
这是我的最终且成功的代码:
Binding bind = null;
for (int r = 1; r <= rows; r++)
{
bind = new Binding("Description");
bind.Source = payments[r - 1];
TextBlock col = new TextBlock();
BindingOperations.SetBinding(col, TextBlock.TextProperty, bind);
col.TextAlignment = TextAlignment.Left;
col.VerticalAlignment = VerticalAlignment.Center;
col.Width = 240;
bdr = new Border();
bdr.BorderBrush = System.Windows.Media.Brushes.Black;
bdr.BorderThickness = new Thickness(2);
Grid.SetColumn(bdr, 0);
Grid.SetRow(bdr, r);
bdr.Child = col;
grdPayments.Children.Add(bdr);
bind = new Binding("Due");
bind.Source = payments[r - 1];
bind.Converter = new MbcsCentral.CurrencyPaddingConverter();
bind.ConverterParameter = "10";
col = new TextBlock();
BindingOperations.SetBinding(col, TextBlock.TextProperty, bind);
col.TextAlignment = TextAlignment.Right;
col.VerticalAlignment = VerticalAlignment.Center;
col.HorizontalAlignment = HorizontalAlignment.Left;
col.Width = 100;
bdr = new Border();
bdr.BorderBrush = System.Windows.Media.Brushes.Black;
bdr.BorderThickness = new Thickness(2);
Grid.SetColumn(bdr, 1);
Grid.SetRow(bdr, r);
bdr.Child = col;
grdPayments.Children.Add(bdr);
NumberEntry vi = new NumberEntry();
bind = new Binding("Paid");
bind.Source = payments[r - 1];
bind.StringFormat = "######0.00";
BindingOperations.SetBinding(vi, NumberEntry.TextProperty, bind);
vi.MaxLength = 10;
vi.Decimals = 2;
vi.Width = 100;
vi.LostFocus += NumberEditor_LostFocus;
vi.PreviewKeyDown += PaidBlock_PreviewKeyDown;
bdr = new Border();
bdr.BorderBrush = System.Windows.Media.Brushes.Black;
bdr.BorderThickness = new Thickness(2);
Grid.SetColumn(bdr, 2);
Grid.SetRow(bdr, r);
bdr.Child = vi;
grdPayments.Children.Add(bdr);
}
grdPayments 现在是 XAML 中的一个空网格:一个占位符。 每个单元格都由一个包裹在边框中的 UiElement 组成,绑定到数据并设置到网格中的正确行/列中。
我不知道我是否会以这种方式处理比这里需要的更多的列,但这是一个简单且非常可行的解决方案,能够简单地将焦点设置在任何单元格后面的代码中,然后进入编辑模式无需单击。
不像 WPF 纯粹主义者可能更喜欢的声明性,但我在编程生涯的早期就了解到,最终重要的是它有效。