我有一个带有3列的WPF Datagrid作为窗口的一部分。 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>
答案 0 :(得分:0)
我99%确定你需要删除:
SelectionUnit="Cell"
答案 1 :(得分:0)
要访问设置为SelectionUnit
Cell
的行,您必须这样做:
grdPayments.SelectedItem = grdPayments.SelectedCells[0].item;
仅当您一次只能选择一个单元格(而不是在扩展模式下)时,它才有效。
答案 2 :(得分:0)
使WPF DataGrid的行为方式与我想要的方式似乎是一个失败的原因:它根本不是为了满足我的需要而设计的。
我所做的是在后面的代码中动态构建一个单元格网格。连续的每个单元格都可以精心设计,以执行我想要的任何操作。
这是我最后的,也是成功的代码:
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纯粹主义者可能不喜欢声明,但我在编程生涯中很早就知道最重要的是它有效。