2011-12-05 2 views
8

WPF Datagrid로 탭하면 첫 번째 셀은 사각형으로 초점을 맞추지 만 파란색으로는 선택하지 않습니다. 탭을 다시 누르면 초점이 이고이 선택됩니다.어떻게하면 WPF Datagrid가 처음으로 셀을 선택했을 때 셀을 선택하게합니까?

실제로 DataGridCell에는 IsSelected = true가 있지만 파란색으로 그려지지 않습니다. 데이터 격자 및 시각 상태를 해킹하려고 시도했지만 먼저 탭을 넣을 때 그리드를 올바르게 다시 칠할 수 없습니다.

이전에 본 적이 있었고 해결책이 있습니까?

코드가 재현 :

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <TextBox Width="100"/> 
     <DataGrid SelectionMode="Single" SelectionUnit="Cell" 
       ItemsSource="{Binding MyItems}" AutoGenerateColumns="True"/> 
    </StackPanel> 
</Window> 

MainWindow.xaml.cs를

using System.Collections.Generic; 
using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      MyItems.Add(new Thingy() { Name = "Frank", Age = 34 }); 
      MyItems.Add(new Thingy() { Name = "Jim", Age = 43 }); 
      MyItems.Add(new Thingy() { Name = "Bob", Age = 56 }); 
      MyItems.Add(new Thingy() { Name = "Harry", Age = 23 }); 

      DataContext = this; 
     } 

     private List<Thingy> _myItems = new List<Thingy>(); 
     public List<Thingy> MyItems 
     { 
      get { return _myItems; } 
     } 
    } 

    public class Thingy 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 
} 

클릭 텍스트 상자에 다음 탭을 명중 --- 셀 (1)이 선택되지 않음

다시 히트 탭 --- 셀 2가 선택되었습니다.

도움을 주시면 감사하겠습니다.

업데이트 : selectedIndex의이 첫 번째 행 지금은 파란색으로 선택입니다 생성시 0으로 설정되어있는 경우 SelectionUnit = FullRow, 나는, 아래의 라인을 따라 약간의 성공이 있었다

. Shift-Tab 등을 처리하는 데는 여전히 약간의 작업이 필요합니다. SelectionMode를 확장 및 Shift-downarrow로 변경하면 두 번째 행이 선택되지만 첫 번째 행은 선택 취소됩니다 (둘 다 선택해야 함) . 만약 내가 다시 그것을 행 2 + 3 올바른 선택하고 그 후 확인 작업을 계속합니다.

protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e) 
    { 
     base.OnIsKeyboardFocusWithinChanged(e); 

     int oldIdx = this.SelectedIndex; 
     this.SelectedIndex = -1; 
     this.SelectedIndex = oldIdx; 
    } 

또한 업데이트 :

는 개인 _selectionAnchor 필드를 설정하여이 문제를 해결했습니다. (감사합니다 ILSpy)

protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e) 
    { 
     base.OnIsKeyboardFocusWithinChanged(e); 

     this.SelectedIndex = -1; 
     this.SelectedIndex = 0; 

     SelectionAnchor = SelectedCells[0]; 
    } 

    protected DataGridCellInfo? SelectionAnchor 
    { 
     get 
     { 
      return typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as DataGridCellInfo?; 
     } 
     set 
     { 
      typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, value); 
     } 
    } 
+0

당신은 hasfocus를 사용해야하지만 긍정적 인 답변이 아니므로 대답으로 게시하지 않을 것이라고 생각합니다. – Paparazzi

+0

흥미롭게도, 디버깅하는 동안'DataGrid'의 속성을 스누핑하려고 시도하는 중에'StackOverflowException'이 발생합니다. –

답변

4

이렇게 할 수 있습니다. 포커스 이벤트를 등록한 다음 원래 소스를 선택된 항목으로 설정하십시오. 파일 뒤에

코드에서 다음
<Window x:Class="WpfApplication1.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="MainWindow" Height="350" Width="525"> 
<StackPanel> 
    <TextBox Width="100"/> 
    <DataGrid SelectionMode="Single" SelectionUnit="Cell" 
      ItemsSource="{Binding MyItems}" AutoGenerateColumns="True" 
      GotFocus="WPF_DataGrid_GotFocus" /> 
</StackPanel> 
</Window> 

:

private void WPF_DataGrid_GotFocus(object sender, RoutedEventArgs e) 
    { 
     (e.OriginalSource as DataGridCell).IsSelected = true; 

    } 

는 나는 그것이 도움이되기를 바랍니다!

+0

저는 실제로 DataGrid 컨트롤을 포기하고 ListView로 돌아가서 이런 종류의 동작을 제어 할 수있게되었습니다. 나는 이것이 올바른 것으로 들리고 그것이 내가 얻은 유일한 것, GuruC에게 감사하기 때문에 이것을 답으로 표시하고있다! –

+0

'DataGrid.SelectionUnit'이'FullRow' 인 경우'DataGridCell' 인'e.OriginalSource'에서 상위'DataGridRow'까지 시각적 트리를 위로 이동하려면'VisualTreeHelper'를 사용해야합니다. 그런 다음 셀 대신에 행에서'IsSelected = true'를 설정해야합니다. 그 외에도이 솔루션이 효과적입니다. –

3

답변이 너무 늦었지만 다른 사이트로 이동하는 데 도움이됩니다.

많은 연구 끝에 Tab 키를 누른 상태에서 요소를 선택하는 방법에 대한 대답을 얻었습니다. 정말 쉽고 XAML에서 한 줄의 코드로 트릭을 만들었습니다. false로 IsTabStop을 설정하여

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

당신은 템플릿 내부에 가서 할 수 초점 모든 요소를 ​​찾기 위해 datagridcell의 시각적 트리를 말하고있다. 어떤 요소를 발견하면 해당 요소에 초점을 맞 춥니 다.

관련 문제