无法在WPF DataGrid中选择第一行

时间:2016-02-09 02:08:02

标签: c# wpf xaml datagrid

我有一个带有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>

3 个答案:

答案 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纯粹主义者可能不喜欢声明,但我在编程生涯中很早就知道最重要的是它有效。