我有一个数据网格应该是一个'输入表'供最终用户使用。 (用户提供数据,单击按钮,程序处理数据)
它绑定到ObservableCollection(User类包含简单的东西,如电子邮件,名称,登录等)
一切都工作得很好......但是,我想允许用户更正他们的输入,即选择一行并从网格中删除它,或清除几个单元格的内容等 - 并非所有字段都是必需的。< / p>
然而,当按下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 :(得分:1)
这是否意味着我在使用绑定时无法删除项目?
不。这只是意味着如果您通过ItemsSource
设置项目,DataGrid
无法控制该集合(它可以是任何类型的集合!)并依赖于您来处理它。
我不知道如何可靠地修改底层集合 - 我怎么知道我是否应该删除Name,Login,Email的值以及我的集合中的哪个用户?
如果您知道该行,则您知道该用户。 User
对象是DataContext
及其单元格的DataGridRow
。您只需从User
集合中删除UsersToCreate
,DataGrid
就会相应更新。
您可以绑定SelectedItem
的{{1}}属性,这将返回所选行的DataGrid
对象。
至于清除给定的单元格并不容易......单元格通常只表示行的数据项的属性,清除其值的唯一方法是将该属性重置为其默认值。在这种情况下,识别财产并不简单。
清除单元格的最佳方法是在其模板中使用User
并使用一些自定义DataGridTemplateColumn
来处理TextBox
事件,并在检测到PreviewKeyUp
时执行TextBox.Clear()
Del 键被按下并释放。
答案 1 :(得分:0)
当然可以:
<DataGrid>
<DataGrid.InputBindings>
<KeyBinding Key="D" Command="{Binding DeleteCommand}" />
<KeyBinding Key="Delete" Command="{Binding DeleteCommand}" />
</DataGrid.InputBindings>
</DataGrid>
编辑: 您可以将所选项目作为参数传递,或者完全按照moncada的建议。为了实现这一点,我认为用户必须从数据网格而不是单元格中选择一行,但现在还不确定。
答案 2 :(得分: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);
}
}
}
虽然它很大,但我认为它非常整洁,因为它允许在几行中选择几个单元格并清除它们而无需重新排序数据网格等。但是,它也允许删除整个如果用户的所有属性都为null,则为行。
可悲的是,我需要读取用户,因为当我只是更新属性时,datagrid不会直观更新 - 集合已更新,但您需要通过dbl单击特定的属性单元格来查看它&#39;擦了擦。
感谢大家的帮助