2015-07-28 3 views
1

У меня есть datagrid, который должен быть «входной таблицей» для конечного пользователя для работы. (Пользователь предоставляет данные, нажимает кнопку и программа обрабатывает данные)Очистка ячеек wpf datagrid пользователем во время выполнения

Он привязан к ObservableCollection (класс пользователя содержит простые вещи, такие как электронная почта, имя, логин и т.д.)

Все работает отлично связывании мудрый .. но я хочу разрешить пользователям исправлять их ввод, т. е. выбирать строку и удалять ее из сетки или очищать содержимое нескольких ячеек и т. д. - не все поля являются обязательными.

Однако, когда нажата клавиша Del, ничего не происходит. Я попытался обработки PreviewKeyDown события и т.д., но я к проблеме описанной ниже:

How I can Delete Selected Row in datagrid wpf?

Означает ли это, я не могу удалить элементы, когда я использую привязки? Я понятия не имею, как я могу достоверно модифицировать базовую коллекцию - как я могу узнать, должен ли я удалить значение Name, Login, Email - и какого пользователя в моей коллекции?

Я думал, что два способа связывания будет заботиться об этом ...

Мой код:

ItemsSource="{Binding ElementName=ThisUc, 
      Path=UsersToCreate, 
      Mode=TwoWay, 
      UpdateSourceTrigger=PropertyChanged}" 


private ObservableCollection<User> _usersToCreate; 
     public ObservableCollection<User> UsersToCreate 
     { 
      get { return _usersToCreate ?? (_usersToCreate = new ObservableCollection<User>()); } 
      set 
      { 
       _usersToCreate = value; 
       RaisePropertyChanged("UsersToCreate"); 
       ProgressBarMax = UsersToCreate.Count; 
      } 
     } 

Приветствия

+0

привязаны к выбранному элементу в вашей модели. как только нажата клавиша удаления, удалите этот элемент из наблюдаемого цвета –

ответ

0

Для дальнейшего использования, это мое полное решение:

private void UserDataGrid_OnPreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     var grid = sender as System.Windows.Controls.DataGrid; 
     if (e.Key == Key.Delete) 
     { 
      //treat each cell individually 
      foreach (var item in grid.SelectedCells) 
      { 
       User user = item.Item as User; 
       if (user == null) 
        continue; 
       //clear the property of the selected cell 
       foreach (var property in typeof(User).GetProperties()) 
       { 
        if (property.Name == item.Column.Header.ToString()) 
        { 
         property.SetValue(user, null, null); 
        } 
       } 
       //recreated the user object 
       User newUser = new User 
       { 
        Login = user.Login, 
        Address = user.Address, 
        Email = user.Email, 
        Name = user.Name, 
        Description = user.Description 
       }; 
       //remove the old one and place the new one to update collection visually (otherwise DataGrid updates when only double-clicked) 
       var index = UsersToCreate.IndexOf(user); 
       UsersToCreate.Remove(user); 
       UsersToCreate.Insert(index, newUser); 
      } 
      //now check if any rows are completely empty - if so, then remove from DGV 
      List<int> indexesToRemove = new List<int>(); 
      foreach (var user in UsersToCreate) 
      { 
       bool hasValue = false; 
       foreach (var property in typeof(User).GetProperties()) 
       { 
        if (property.GetValue(user, null) != null) 
        { 
         hasValue = true; 
        } 
       } 
       if (!hasValue) 
       { 
        indexesToRemove.Add(UsersToCreate.IndexOf(user)); 
       } 
      } 
      //go upside down to avoid index out of range (first remove last rows indexes) 
      for (int i = indexesToRemove.Count - 1; i >= 0; i--) 
      { 
       var index = indexesToRemove[i]; 
       UsersToCreate.RemoveAt(index); 
      } 
     } 
    } 

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

К сожалению, мне нужно прочитать пользователя, так как когда я просто обновляю свойства, datagrid не обновляется визуально - коллекция обновляется, но вам нужно dbl-щелкнуть по определенной ячейке свойства, чтобы увидеть, что она была протерта ,

Спасибо за помощь

+0

Рад, что вы сделали это :) Если это то, что сработало для вас, отметьте его как ответ, чтобы другие могли найти это легко – almulo

1

Означает ли это, я не могу удалить элементы, когда я использую связывание?

Nope. Это просто означает, что если вы настраиваете свои позиции через ItemsSource, DataGrid не имеет контроля над этой коллекцией (это может быть любой тип коллекции!) И полагается на вас, чтобы справиться с этим.

Я понятия не имею, как я могу надежно модифицировать базовую коллекцию - как я могу узнать, должен ли я удалить значение Name, Login, Email - и какого пользователя в моей коллекции?

Если вы знаете строку, вы знаете пользователя. Объектом User является DataContextDataGridRow и его ячейки. Вам просто нужно удалить User из коллекции UsersToCreate, и соответственно обновится DataGrid.

Вы можете сделать это, связывая свойство SelectedItem объекта DataGrid, которое вернет объект User выбранной строки.

Что касается очистки данной ячейки, это не так просто ... Ячейки обычно просто представляют свойства элемента данных строки, единственный способ очистить его значение - сбросить это свойство до значения по умолчанию. В этом случае идентификация свойства не проста.

Лучший способ очистить клетку использует DataGridTemplateColumn с некоторыми обычаями TextBox внутри своего шаблона, который обрабатывает событие PreviewKeyUp и делает TextBox.Clear(), когда он обнаруживает ключ Del нажата и отпущена.

+0

Спасибо - я выложу свое полное решение здесь :) – Bartosz

0

Конечно, вы можете:

<DataGrid> 
    <DataGrid.InputBindings> 
     <KeyBinding Key="D" Command="{Binding DeleteCommand}" /> 
     <KeyBinding Key="Delete" Command="{Binding DeleteCommand}" /> 
    </DataGrid.InputBindings> 
</DataGrid> 

EDIT: Вы можете передать выбранный элемент в качестве параметра или сделать именно так, как предполагает Монкада. Для этого я думаю, что пользователь должен выбрать строку из datagrid, а не ячейки, но не уверен в этом прямо сейчас.

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