2011-12-05 42 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

任何幫助非常感謝,謝謝。

更新:

當SelectionUnit = FullRow,我曾沿如下所示的線取得了一些成功,如果SelectedIndex的是在創建第一行現在藍色選擇設置爲0。它仍然需要一些工作來應付shift-tab等等。仍然存在一個問題,因爲當我將SelectionMode更改爲extended並按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',那麼你必須使用'VisualTreeHelper'來將可視化樹從'DataGridCell'的'e.OriginalSource'行走到父'DataGridRow'。然後您必須在行上而不是在單元格上設置「IsSelected = true」。除此之外,這個解決方案的作品 –

3

我知道我的回答爲時已晚,但它有助於其他瀏覽本網站。

經過大量的研究,我得到了如何選擇元素,同時選項卡的答案。 這非常簡單,並且是XAML中的一行代碼,

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

通過設置IsTabStop爲false,你說的是datagridcell的可視化樹去它的模板內,發現是能夠集中的任何元素。如果它找到某個元素,那麼它會關注該元素。

相關問題