DataGridCell 向下时是 TextBlock,向上时是 TextBox
DataGridCell is a TextBlock when going down, but TextBox when going up
所以,我有一个 DataGrid,它包含如下所示的元素:
<DataGridTextColumn Header="Dto 1" Binding="{Binding Path=Dto1}">
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="{x:Type TextBox}">
<EventSetter Event="PreviewKeyDown" Handler="TextBox_PreviewKeyDown"/>
<EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
PreviewKeyDown 工作得很好,当我上升时,我可以毫无问题地回到单元格。在我看来,出于所有意图和目的,我在那里有一个 TextBox。
现在,当我尝试从事件中的单元格下降时:
private void dgPropuestas_GotFocus(object sender, RoutedEventArgs e) {
var cell = e.OriginalSource as DataGridCell;
if (cell != null) {
var cp = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(cell, 0), 0) as ContentPresenter;
var tb = cp.Content as TextBlock;
if (tb != null)
tb.Focus();
}
}
(注意:我手动放置了两次 VisualTreeHelper 方法,我确实有 FindVisualChildren 方法,但是我手动遍历了树,为了加快一点速度,我手动放置了它)
如果我尝试将 tb 声明为 cp.Content 作为 TextBox,我得到一个 null。
由于某种原因,ContentPresenter 内部有一个 TextBlock,而不是 TextBox。
FindVisualChildren(cell) returns 一个空的 IEnumerable。
为什么这是个问题?因为我需要能够对文本调用 SelectAll(),而 textBlock 不提供该选项。
任何帮助是极大的赞赏。
提前致谢!
稍后编辑:显然,当不处于编辑模式时,数据网格包含一个文本块。在编辑模式下,一个文本框。现在,datagrid.BeginEdit() 似乎不起作用,因为它没有初始化 TextBox,也没有触发 PrepareCellForEditing 事件。
完全以错误的方式接近这个。您订阅了 TextBox
上的活动,因此 sender
将始终显示为 TextBox
。
鉴于 TextBox 不会使用 BeginEditing() 或 isEditing = true 进行初始化,问题已通过将字段声明为文本框并将它们强加到数据网格上来解决:
<DataGridTemplateColumn Header="Dto 2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Dto2}" GotFocus="TextBox_GotFocus" PreviewKeyDown="TextBox_PreviewKeyDown"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
所以,我有一个 DataGrid,它包含如下所示的元素:
<DataGridTextColumn Header="Dto 1" Binding="{Binding Path=Dto1}">
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="{x:Type TextBox}">
<EventSetter Event="PreviewKeyDown" Handler="TextBox_PreviewKeyDown"/>
<EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
PreviewKeyDown 工作得很好,当我上升时,我可以毫无问题地回到单元格。在我看来,出于所有意图和目的,我在那里有一个 TextBox。
现在,当我尝试从事件中的单元格下降时:
private void dgPropuestas_GotFocus(object sender, RoutedEventArgs e) {
var cell = e.OriginalSource as DataGridCell;
if (cell != null) {
var cp = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(cell, 0), 0) as ContentPresenter;
var tb = cp.Content as TextBlock;
if (tb != null)
tb.Focus();
}
}
(注意:我手动放置了两次 VisualTreeHelper 方法,我确实有 FindVisualChildren 方法,但是我手动遍历了树,为了加快一点速度,我手动放置了它)
如果我尝试将 tb 声明为 cp.Content 作为 TextBox,我得到一个 null。 由于某种原因,ContentPresenter 内部有一个 TextBlock,而不是 TextBox。 FindVisualChildren(cell) returns 一个空的 IEnumerable。
为什么这是个问题?因为我需要能够对文本调用 SelectAll(),而 textBlock 不提供该选项。 任何帮助是极大的赞赏。 提前致谢!
稍后编辑:显然,当不处于编辑模式时,数据网格包含一个文本块。在编辑模式下,一个文本框。现在,datagrid.BeginEdit() 似乎不起作用,因为它没有初始化 TextBox,也没有触发 PrepareCellForEditing 事件。
完全以错误的方式接近这个。您订阅了 TextBox
上的活动,因此 sender
将始终显示为 TextBox
。
鉴于 TextBox 不会使用 BeginEditing() 或 isEditing = true 进行初始化,问题已通过将字段声明为文本框并将它们强加到数据网格上来解决:
<DataGridTemplateColumn Header="Dto 2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Dto2}" GotFocus="TextBox_GotFocus" PreviewKeyDown="TextBox_PreviewKeyDown"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>