【问题标题】:How to select a TextBox inside a datagrid cell when the cell is selected in WPF?在 WPF 中选择单元格时,如何在数据网格单元格中选择文本框?
【发布时间】:2016-11-23 13:48:14
【问题描述】:

我有一个数据网格,其中第一列的单元格被文本框覆盖。如果我用鼠标选择“单元格”没问题,因为我只能点击文本框,但是当我用键盘导航时,我可以导航到下面的单元格。我尝试设置单元格样式,但 TextBox 继承了设置。有没有办法在选中下面的单元格时将焦点移到 TextBox 上?

<DataGrid x:Name="buildDataGrid" 
        ItemsSource="{Binding BuildData}" 
        AutoGenerateColumns="False"
        CanUserReorderColumns="False" 
        CanUserSortColumns="False" 
        CanUserResizeRows="False" 
        SelectionUnit="CellOrRowHeader" 
        CanUserAddRows="False" 
        CanUserDeleteRows="False" 
        KeyboardNavigation.TabNavigation="None"
        Margin="0,0,10,0" IsReadOnly="True">
  <DataGrid.CellStyle>
      <Style TargetType="DataGridCell" >
          <Style.Setters>
              <Setter Property="IsEnabled" Value="True"/>
              <Setter Property="IsHitTestVisible" Value="False" />
          </Style.Setters>
      </Style>
  </DataGrid.CellStyle>
  <DataGrid.Columns>
      <DataGridTemplateColumn Header="Serial Number"  
                              MinWidth="200" 
                              Width="*" 
                              x:Name="componentSerialNumberDataGridTemplate">
          <DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                  <TextBox Text="{Binding SerialNumber, UpdateSourceTrigger=PropertyChanged}" 
                           x:Name="snoTextBox" 
                           BorderThickness="0" 
                           Focusable="True" 
                           GotFocus="snoTextBox_GotFocus">
                      <TextBox.InputBindings>
                          <KeyBinding Command="{Binding SerialNumberEnterCommand}" 
                                      CommandParameter="{Binding Path=Text, ElementName=snoTextBox}" 
                                      Key="Return"/>
                      </TextBox.InputBindings>
                  </TextBox>
              </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    您需要创建强制文本框聚焦的行为 (myTextBox.Focus())。 此行为应分配给 TextBox 实例并绑定到 DataCell 的属性 IsFoucsed 的实例。 类似的东西:

     <TextBox Text="{Binding SerialNumber, UpdateSourceTrigger=PropertyChanged}" 
                           x:Name="snoTextBox" 
                           BorderThickness="0" 
                           Focusable="True" 
                           local:Behaviour.ForceFoucusBoolean="{Binding IsFocused, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridCell}}}"
                           GotFocus="snoTextBox_GotFocus">
                      <TextBox.InputBindings>
                          <KeyBinding Command="{Binding SerialNumberEnterCommand}" 
                                      CommandParameter="{Binding Path=Text, ElementName=snoTextBox}" 
                                      Key="Return"/>
                      </TextBox.InputBindings>
                  </TextBox>
    

    你的行为是这样的:

     class Behaviour
    {
    
    
        public static bool GetForceFoucusBoolean(DependencyObject obj)
        {
            return (bool)obj.GetValue(ForceFoucusBooleanProperty);
        }
    
        public static void SetForceFoucusBoolean(DependencyObject obj, bool value)
        {
            obj.SetValue(ForceFoucusBooleanProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for ForceFoucusBoolean.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ForceFoucusBooleanProperty =
            DependencyProperty.RegisterAttached("ForceFoucusBoolean", typeof(bool), typeof(Behaviour), new PropertyMetadata(null,
                (o, e) =>
                {
    
                    TextBox  tb = o as TextBox;
                    if (tb != null)
                    {
                        bool foucs = Convert.ToBoolean(e.NewValue);
                        if (selctAll)
                        {
                            tb.Foucs();
                        }
                        else
                        {
                            tb.Unfocus();
                        }
                    }
    
                }));
    
    
    }
    

    这应该适合你。

    【讨论】:

    • 谢谢@Mr.B,我试过了。不幸的是,它抱怨Default value type does not match type of property 'ForceFoucusBoolean'.