2009-07-09 2 views
6
 <data:DataGridTemplateColumn Header="Name"> 
     <data:DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Name}"> 
      </DataTemplate> 
     </data:DataGridTemplateColumn.CellTemplate> 
     <data:DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <TextBox Text="{Binding Name}"> 
      </DataTemplate> 
     </data:DataGridTemplateColumn.CellEditingTemplate> 
    </data:DataGridTemplateColumn>    

템플릿 열은 분명합니다. 맞습니까? 그게 뭐가 잘못 되었을까요? 그래서, 여기에 있습니다 - 사용자가 Tab 키를 치면서 DataGrid를 탐색 할 때 TextBox에서 텍스트를 편집하려면 Tab 키를 두 번 눌러야합니다 (!). 사용자가 열 포커스를 얻 자마자 편집 가능하게 만들 수 있습니까? 입력을 시작한 후에도 가능합니까?WPF DataGridTemplateColumn. 내가 놓친 게 있니?

확인.

이 문제는 각 셀에 먼저 포커스를받는 콘텐츠 컨트롤의 편집기를두고 있다는 사실에서 유래
if (Grid.CurrentColumn.Header.ToString() == "UserName") 
     { 
      if (e.Key != Key.Escape) 
      { 
       Grid.BeginEdit(); 

       // Simply send another TAB press 
       if (Keyboard.FocusedElement is Microsoft.Windows.Controls.DataGridCell) 
       { 
        var keyEvt = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Tab) { RoutedEvent = Keyboard.KeyDownEvent }; 
        InputManager.Current.ProcessInput(keyEvt); 
       } 
      } 
     } 

답변

8

, 다음 탭이 : 나는 아래의 코드를 넣어() Grid.KeyUp에 - 나는 방법을 발견 다시 한 번 편집자에게. 당신이 GenerateEditingElement 방법에 DataGridTemplateColumn에 대한 코드를 살펴있는 경우는이 않는 방법 LoadTemplateContent 호출합니다.

private FrameworkElement LoadTemplateContent(bool isEditing, object dataItem, DataGridCell cell) 
{ 
    DataTemplate template = ChooseCellTemplate(isEditing); 
    DataTemplateSelector templateSelector = ChooseCellTemplateSelector(isEditing); 
    if (template != null || templateSelector != null) 
    { 
     ContentPresenter contentPresenter = new ContentPresenter(); 
     BindingOperations.SetBinding(contentPresenter, ContentPresenter.ContentProperty, new Binding()); 
     contentPresenter.ContentTemplate = template; 
     contentPresenter.ContentTemplateSelector = templateSelector; 
     return contentPresenter; 
    } 

    return null; 
} 

그것에서 템플릿을 넣어 새 콘텐츠 발표자를 생성하는 방법을 참조하십시오 다른 사람들이 처리 한 문제를 다양한 방법으로 처리 할 수 ​​있기 때문에이 항목을 처리하기 위해 자체 열 유형을 파생시킵니다. 당신이있는 경우

<tk:DataGridTemplateColumn.CellEditingTemplate> 
    <DataTemplate> 
     <Grid FocusManager.FocusedElement="{Binding ElementName=txt1}"> 
     <TextBox Name="txt1" Text="{Binding [email protected]}" 
        BorderThickness="0" GotFocus="TextBox_GotFocus"/> 
     </Grid> 
    </DataTemplate> 
</tk:DataGridTemplateColumn.CellEditingTemplate> 

(나는이 코드를 테스트 havent 한)가 같은 문제점을 해결하기위한 포커스 관리자를 사용하는이 example에서 (그래서 난 여분의 요소를 만들거나 포커스를받을 수있는 콘텐츠 발표자를 설정 해달라고) 사용자 정의 컨트롤을 편집기로 사용하면 포커스 관리자에서 패턴을 사용하거나 OnLoaded 이벤트에 이벤트 핸들러를 사용할 수 있습니다.

+0

가 치료를 작동하지만이 정말 못생긴 해킹 : 더 정보에 대한

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { try { ((TextBox)sender).SelectAll(); } catch (Exception ex) { GlobalDebug.debugForm.WriteText(ex); } } private void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e) { try { // If its a triple click, select all text for the user. if (e.ClickCount == 3) { ((TextBox)sender).SelectAll(); return; } // Find the TextBox DependencyObject parent = e.OriginalSource as UIElement; while (parent != null && !(parent is TextBox)) { parent = System.Windows.Media.VisualTreeHelper.GetParent(parent); } if (parent != null) { if (parent is TextBox) { var textBox = (TextBox)parent; if (!textBox.IsKeyboardFocusWithin) { // If the text box is not yet focussed, give it the focus and // stop further processing of this click event. textBox.Focus(); e.Handled = true; } } } } catch (Exception ex) { GlobalDebug.debugForm.WriteText(ex); } } 

, 내 블로그를 봐 기능 – David

+0

FocusManager의 방법의이 종류는 잘 작동 내용이 선택 얻으려면, 당신은 또한 가지고 초점 방법을 추가 할 수 있습니다. 개인 무효 StrikeTextBox_GotFocus (개체를 보낸 사람, RoutedEventArgs e)에 { var에 텍스트 상자 = (텍스트 상자) 보낸 사람을 ; Dispatcher.BeginInvoke (새 작업 (textBox.SelectAll)); } – Neil

0

내 접근 방식은로드 할 때 원하는 템플릿 요소에 포커스를 설정하는 TriggerAction을 사용하는 것입니다.

트리거

은 매우 간단합니다 :

public class TakeFocusAndSelectTextOnVisibleBehavior : TriggerAction<TextBox> 
{ 
    protected override void Invoke(object parameter) 
    { 
     Dispatcher.BeginInvoke(
      DispatcherPriority.Loaded, 
      new Action(() => 
      { 
       AssociatedObject.Focus(); 
       AssociatedObject.SelectAll(); 
      })); 
    } 
} 

DataTemplate을은 다음과 같습니다 : 당신은 다른 요소 유형에 대한 다른 트리거를 작성할 수

<DataTemplate> 
    <TextBox Text="{Binding Path=Price, Mode=TwoWay}" 
       MinHeight="0" 
       Padding="1,0" 
       Height="20"> 
     <Interactivity:Interaction.Triggers> 
      <Interactivity:EventTrigger EventName="Loaded"> 
       <Behaviors:TakeFocusAndSelectTextOnVisibleBehavior /> 
      </Interactivity:EventTrigger> 
     </Interactivity:Interaction.Triggers> 
    </TextBox> 
</DataTemplate> 

.

+1

이 기능을 사용하려면 Expression Blend의 dll이 필요하다고 생각합니다. – Neil

7

당신이 직면 한 문제는 DataGridTemplateColumn 내의 컨트롤 (예 : TextBox)이 DataGridCell 내에 포함되어 있다는 것입니다. 기본적으로 DataGridCell에는 탭 중지 기능이 있습니다. 따라서 TextBox 컨트롤에 포커스를 얻으려면 Tab 키를 두 번 눌러야하는 이유입니다. 해결 방법은 DataGridCell의 탭 중지 기능을 비활성화하는 것입니다. 이 작업은 DataGridCell의 스타일을 통해 수행 할 수 있습니다.

<Style TargetType="{x:Type DataGridCell}"> 
    <Setter Property="KeyboardNavigation.IsTabStop" Value="False" /> 
</Style> 
3

여기 내 접근 방식 :

는 여기에 솔루션입니다. @ Nalin Jayasuriya에 매우 가깝게 대답하지만 스타일을 만들고 싶지 않았습니다. 또한이 솔루션은 TextBox의 텍스트를 선택합니다. 어쨌든 - 구멍 DataGrid의 XAML은 다음과 같습니다.

<DataGrid Name="TextBlockDataGrid" ItemsSource="{Binding Path=Rows}" Style="{StaticResource DefaultSettingsDataGrid}"> 
<DataGrid.Columns> 
    <DataGridTextColumn Binding="{Binding Text}" IsReadOnly="True"/> 
    <DataGridTemplateColumn Width="*"> 
     <DataGridTemplateColumn.CellStyle> 
      <Style TargetType="{x:Type DataGridCell}"> 
       <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/> 
      </Style> 
     </DataGridTemplateColumn.CellStyle> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <Border BorderThickness="{Binding ErrorBorderThickness}" BorderBrush="{Binding ErrorBorderBrush}"> 
        <TextBox Text="{Binding UserText, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 
          HorizontalAlignment="Right" 
          GotKeyboardFocus="TextBox_GotKeyboardFocus" 
          PreviewMouseDown="TextBox_PreviewMouseDown" 
          Style="{StaticResource DefaultTextBox}"/> 
       </Border> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 

그리고 코드 숨김.... :(나는 MS가 제공하는 좋은 방법을 찾을 텐데 http://blog.baltz.dk/post/2014/11/28/WPF-DataGrid-set-focus-and-mark-text

관련 문제