0

当单元格被选中并处于编辑模式时,我在 WPF 中以编程方式访问 DataGridTemplateColumn.CellEditingTemplate 中的文本框时遇到问题。

这是我的 DataGrid 的 XAML:

<DataGrid x:Name="OrderLinesGrid"
          Style="{StaticResource DataGridStyle}"
          SelectionMode="Single"
          SelectionUnit="Cell"
          ItemsSource="{Binding OrderLines}">
  <DataGrid.Columns>
    <DataGridTemplateColumn x:Name="NumberColumn"
                            Header="Varenr."
                            MinWidth="100">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Number}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
      <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
          <TextBox Text="{Binding Number}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

选择单元格时如何访问该文本框?如果可以帮助您,这是显示 DataGrid 的可视化树的图像:

DataGrid 可视化树

我在 DataGridCell GotFocus 事件中尝试了以下操作,但没有运气。它只是返回 NULL,因为它没有找到。

private void DataGridCellGotFocus(object sender, RoutedEventArgs e)
{
    var cell = sender as DataGridCell;
    var textBox = FindChild<TextBox>(cell, null);
}

FindChild 方法如下:

/// <summary>
/// Finds a Child of a given item in the visual tree. 
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter. 
/// If not matching item can be found, 
/// a null parent is being returned.</returns>
public static T FindChild<T>(DependencyObject parent, string childName)
    where T : DependencyObject
{
    // Confirm parent and childName are valid. 
    if (parent == null) return null;

    T foundChild = null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
            // recursively drill down the tree
            foundChild = FindChild<T>(child, childName);

            // If the child is found, break so we do not overwrite the found child. 
            if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
            var frameworkElement = child as FrameworkElement;
            // If the child's name is set for search
            if (frameworkElement != null && frameworkElement.Name == childName)
            {
                // if the child's name is of the request name
                foundChild = (T)child;
                break;
            }
        }
        else
        {
            // child element found.
            foundChild = (T)child;
            break;
        }
    }

    return foundChild;
}

我怀疑它与 DataTemplate 有关,但我需要一些关于如何选择 TextBox 子元素的建议?

4

3 回答 3

3

我认为你应该尽可能避免使用VisualTreeHelper。如果我理解,您可以将您的登录信息封装在CellEditingCommand

<DataGridTemplateColumn.CellEditingTemplate>
  <DataTemplate>
    <TextBox Text="{Binding Number}">
      <i:Interaction.Triggers>
        <i:EventTrigger EventName="GotFocus">
          <i:InvokeCommandAction Command="{Binding CellEditingCommand}" />
        </i:EventTrigger>
      </i:Interaction.Triggers>
    </TextBox>
  </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

您也可以使用行为

更新

<DataTemplate>
    <TextBox Text="{Binding Number}">
        <Interactivity:Interaction.Triggers>
            <Interactivity:EventTrigger EventName="Loaded">
                <TriggerActions:TakeFocusAction />
            </Interactivity:EventTrigger>
        </Interactivity:Interaction.Triggers>
    </TextBox>
</DataTemplate>

并触发动作

public class TakeFocusAction : TriggerAction<UIElement>
{
    protected override void Invoke(object parameter)
    {
        AssociatedObject.Focus();
    }
}
于 2012-11-30T12:12:50.573 回答
1
ContentPresenter presenter = e.Column.GetCellContent(e.Row);    
TextBox textBox = presenter.ContentTemplate.FindName("nameOfYourTextBox", presenter) as TextBox;
于 2013-04-30T09:26:45.167 回答
0

我认为你应该处理PreparingCellForEdit:某事

void MainDataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
   TextBox tb = e.Column.GetCellContent(e.Row) as TextBox;
}

请参阅:如何知道用户编辑 WPF DataGrid 单元格时为空?

于 2012-12-01T08:33:08.520 回答