2010-10-01 4 views
8

В WinForm DataGridView он автоматически выбирает первую строку при инициализации. Это сбило меня с ума, когда я попытался отключить эту функцию. Переходя к WPF DataGrid, похоже, Microsoft решила отключить эту функцию, что, я думаю, неплохо. Однако у меня есть трудное время, чтобы включить эту функцию сейчас. Для некоторых DataGrid я хочу, чтобы первая строка была выбрана автоматически после заполнения сетки посредством привязки данных. В Интернете есть несколько предложений, но я не мог сделать эту работу. Я надеюсь на лучшую удачу здесь.Как выбрать строку или ячейку в WPF DataGrid программно?

ответ

9

IsSynchronizedWithCurrentItem = "true".

EDIT:

Для решения вашего комментария, я полагаю, что SelectionUnit вашего DataGrid установлен в положении "Cell", это? Хорошо, я не уверен, что это лучшее решение, но одна вещь, которую вы можете сделать, это обработать событие Loaded для DataGrid и вручную установить выбранную ячейку в коде. Таким образом, вы будете иметь что-то вроде этого:

<DataGrid x:Name="dg" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" 
      SelectedCellsChanged="dg_SelectedCellsChanged" SelectionUnit="Cell" 
      Loaded="dg_Loaded"> 
    ... 
</DataGrid> 

Event-Handler:

private void dg_Loaded(object sender, RoutedEventArgs e) 
{ 
    if ((dg.Items.Count > 0) && 
     (dg.Columns.Count > 0)) 
    { 
     //Select the first column of the first item. 
     dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[0]); 
     dg.SelectedCells.Add(dg.CurrentCell); 
    } 
} 

Обратите внимание, что это будет работать только если DataGrid.SelectionUnit установлен в "Cell". В противном случае, я считаю, что это вызовет исключение.

EDIT2:

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> 
     <Button Click="Button_Click">Reset</Button> 
     <DataGrid x:Name="dg" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" 
       SelectionUnit="Cell" 
       DataContextChanged="dg_DataContextChanged" 
       ItemsSource="{Binding Items}" 
       Loaded="dg_Loaded"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Binding="{Binding}"/> 
      </DataGrid.Columns> 
     </DataGrid> 
    </StackPanel> 
</Window> 

Code-Behind:

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.LoadItems(); 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      this.LoadItems(); 
     } 

     private void LoadItems() 
     { 
      this.DataContext = new { Items = new List<string> { "Item1", "Item2", "Item3" } }; 
      this.SelectFirstItem(); 
     } 

     private void dg_Loaded(object sender, RoutedEventArgs e) 
     { 
      SelectFirstItem(); 
     } 

     void SelectFirstItem() 
     { 
      if ((dg.Items.Count > 0) && 
       (dg.Columns.Count > 0)) 
      { 
       //Select the first column of the first item. 
       dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[0]); 
       dg.SelectedCells.Add(dg.CurrentCell); 
      } 
     } 

     private void dg_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
     { 
      this.SelectFirstItem(); 
     } 
    } 
} 
+0

Большое спасибо за отзыв. Я просто попробовал. Установка его в true приведет к тому, что первая строка DataGrid «Highlighted», но не будет выбрана. Мне нужно событие SelectedCellsChanged для запуска. Итак, как мне сделать это событие также уволенным? – newman

+0

См. EDIT. Надеюсь, поможет. – ASanch

+0

@karmicpuppet: Этот код работает в событии dg_Loaded. Однако он работает в событии DataContextChanged.По существу, одна и та же сетка используется повторно. Каждый раз, когда задан контекст данных данных, я хочу, чтобы первая строка была выбрана автоматически, которая должна запускать событие SelectedCellsChanged, потому что я полагаюсь на это. – newman

0

Вы могли бы попробовать это.

 this.dataGrid.SelectionMode = DataGridSelectionMode.Single; 

     // Selects the 4th row. 
     this.dataGrid.SelectedIndex = 3; 
+0

Этот номер предназначен для выбора строки. –

+0

@Avatar: Я просто попробовал ваше предложение. Кажется, он имеет тот же эффект, что и IsSynchronizedWithCurrentItem. Таким образом, он просто выделяет строку, но я не получаю событие SelectedCellsChanged. К сожалению, нет события «SelectedRowChanged» или что-то в этом роде. По сравнению с WinForm DataGridView, WPF DataGrid имеет очень мало событий. – newman

+0

@miliu Событие SelectedCellsChanged должно срабатывать, не знаю, в чем проблема. У меня есть образец здесь. Пожалуйста, проверьте это. Это может дать вам некоторую идею. http://www.filefactory.com/file/b3bhf1d/n/DataGridCheckBoxSelection.zip –

1

Я рад сообщить, я нашел решение этой проблемы путем ItemContainerGenerator.StatusChanged события.

dataGrid.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged); 

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e) 
     { 
      if (dataGrid.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) 
      { 
       dataGrid.SelectedIndex = 0; 
      } 
     } 

Это выглядит, когда это событие запущено со статусом Containers Generated, dataGrid полностью инициализирован. Для меня это больше похоже на событие DataBindingComplete DataGridView в WinForm. Если это так, событие «DataContextChanged» действительно следует называть событием «DataContextChanging».

Это было вдохновлено сообщением here Я случайно нашел, ища другую подсказку.

+0

На самом деле, я просто понял, что событие ItemContainerGenerator_StatusChanged может быть запущено слишком много раз. Я вернулся к событию DataContextChanged и сделал его работу через Dispatcher.BeginInvoke. – newman

3

Вы можете сделать это последовательно в событии DataGrid.Loaded. Просто получите первый ряд и загоните строку в событие выбора.

void MyGridLoaded(...) { 
DataGridRow r = yourGrid.ItemContainergenerator.ContainerFromIndex(0) as DataGridRow; 
    if(r != null) { 
    r.IsSelected = false; 
    r.IsSelected = true; 
    } 

} 

Я не уверен, что это ошибка, потому что вы не можете быть гарантировано иметь событие выбора огня от вашего объекта до тех пор, пока элемент управления будет загружено. Не знаю.

Смежные вопросы