2011-12-05 14 views
8

Khi tôi tab vào bảng dữ liệu WPF nó tập trung ô đầu tiên (với hình chữ nhật) nhưng không chọn nó (màu xanh lam). Nếu tôi nhấn lại tab, nó tập trung chọn nó.Làm thế nào để bạn làm cho bảng dữ liệu WPF chọn một ô khi bạn lần đầu tiên tab vào nó

Tôi nghĩ DataGridCell thực sự có IsSelected = true, nhưng nó không được sơn màu xanh lam. Tôi đã cố gắng hack xung quanh với các dữ liệu và trạng thái trực quan nhưng tôi không thể làm cho nó repaint lưới chính xác khi bạn đầu tiên tab in.

Có ai nhìn thấy điều này trước và bạn có một giải pháp?

mã để tái sản xuất:

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; } 
    } 
} 

nhấp chuột vào TextBox, sau đó tab nhấn --- cell 1 không được chọn

tab lần truy cập lại --- ô 2 được chọn

Bất kỳ trợ giúp nào được đánh giá cao, cảm ơn.

Cập nhật:

Khi SelectionUnit = FullRow, tôi đã có một số thành công dọc theo dòng hiển thị dưới đây, nếu SelectedIndex được đặt thành 0 khi tạo hàng đầu tiên nay chọn màu xanh lam. Nó vẫn cần một số công việc để đối phó với shift-tab vv Vẫn còn một vấn đề mặc dù bởi vì khi tôi thay đổi SelectionMode để mở rộng và nhấn shift-downarrow hàng thứ hai được chọn nhưng hàng đầu tiên được bỏ chọn (cả hai nên được chọn) . Nếu tôi làm điều đó một lần nữa hàng 2 + 3 được chọn là đúng và nó tiếp tục làm việc ok sau đó.

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

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

Hơn nữa Cập nhật:

Cố định vấn đề mà bằng cách thiết lập các lĩnh vực _selectionAnchor tin. (Cảm ơn 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

Tôi nghĩ bạn cần sử dụng hasfocus nhưng không tích cực nên tôi không đăng câu trả lời. – Paparazzi

+0

Thật kỳ lạ, tôi nhận được một 'StackOverflowException' trong khi cố gắng Snoop các thuộc tính của' DataGrid' trong khi gỡ lỗi. –

Trả lời

4

Bạn có thể làm như thế này. Đăng ký sự kiện lấy nét và sau đó đặt nguồn gốc làm mục đã chọn.

<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> 

Sau đó, trong đoạn code behind file:

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

    } 

Tôi hy vọng nó sẽ giúp!

+0

Tôi đã thực sự từ bỏ việc kiểm soát DataGrid và quay trở lại ListView nơi tôi có nhiều quyền kiểm soát hơn đối với loại hành vi này. Tôi đánh dấu đây là câu trả lời vì nó có vẻ đúng và đó là người duy nhất tôi nhận được, cảm ơn GuruC! –

+0

Nếu 'DataGrid.SelectionUnit' là' FullRow' thì bạn phải sử dụng 'VisualTreeHelper' để di chuyển cây trực quan từ' e.OriginalSource' thành 'DataGridCell' thành cha' DataGridRow'. Sau đó, bạn phải đặt 'IsSelected = true' trên hàng thay vì trên ô. Khác hơn là giải pháp này hoạt động. –

3

Tôi biết câu trả lời của tôi đã quá muộn nhưng sẽ giúp điều hướng khác đến trang web này.

Sau nhiều nghiên cứu, tôi nhận được câu trả lời về cách chọn phần tử trong khi tabbing. Nó thực sự dễ dàng và là một dòng mã trong XAML đã thực hiện thủ thuật đó;

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

Bằng cách đặt IsTabStop false bạn đang nói cây thị giác của datagridcell đi vào bên trong mẫu của mình và tìm thấy bất kỳ yếu tố đó là tập trung thể. Nếu nó tìm thấy một số phần tử thì nó tập trung phần tử đó.

Các vấn đề liên quan