gpt4 book ai didi

c# - 删除 DataGrid 中自动生成的行

转载 作者:行者123 更新时间:2023-11-30 22:05:08 26 4
gpt4 key购买 nike

我有一个数据网格。它绑定(bind)到名为 People 的 Person 集合。

允许用户添加新行,我的意思是 CanUserAddRows = true

Enter 键在我的 DataGrid 中用作 TAB 键。

我的 DataGrid 中有三列,即:FirstName、LastName、City。名字是必需的。另外两个不是强制性的。

当用户在最后一行(自动生成的行)的第一个单元格上点击 Enter 时,如果该单元格为空,则计算机会猜测用户不想向 DataGrid 添加更多数据,并且焦点移动到 DataGrid 外部的按钮。

到目前为止一切正常。

问题:

通过在最后一行的第一个单元格上按 Enter 并将其保持为空,DataGrid 外部的按钮将获得焦点。那时我不希望用户看到 DataGrid 中的最后一个空行。

我尝试过的:

我尝试了两个事件:1. GotFocus 和 2. LostFocus

在 DataGrid 的 GotFocus 事件中,我设置了 CanUserAddRows = true在 DataGrid 的 LostFocus 事件中,我设置了 CanUserAddRows = false

但不幸的是,当 DataGrid 单元格内的 textBlock 获得焦点时,这不起作用,DataGrid 认为它已经失去了焦点。因此,CanUserAddRows 设置为 false,我收到错误消息。

我的代码:

人.cs

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
}

MainWindowViewModel.cs

public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
People = new ObservableCollection<Person>();
}

private ObservableCollection<Person> _people;
public ObservableCollection<Person> People
{
get
{
return _people;
}
set
{
_people = value;
OnPropertyChanged("People");
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

主窗口.xaml

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">

<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="93*"/>
<RowDefinition Height="14*"/>
</Grid.RowDefinitions>
<DataGrid x:Name="maindg" AutoGenerateColumns="True" ItemsSource="{Binding People}" Margin="0,0,0.4,-0.2" Grid.RowSpan="2" Grid.ColumnSpan="2"
PreviewKeyDown="DataGrid_KeyDown_1" SelectedIndex="0" GridLinesVisibility="Vertical"
SelectionMode="Single" SelectionUnit="CellOrRowHeader" >
</DataGrid>

<Button Height="20" Width="50" Content="Save" Margin="2.8,9.8,10.4,11.8" Grid.Column="1" Grid.Row="1" x:Name="btnSave" />
</Grid>
</Window>

主窗口.xaml.cs

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private int FindRowIndex(DataGridRow row)
{
DataGrid dataGrid =
ItemsControl.ItemsControlFromItemContainer(row)
as DataGrid;

int index = dataGrid.ItemContainerGenerator.
IndexFromContainer(row);

return index;
}

private object ExtractBoundValue(DataGridRow row,
DataGridCell cell)
{
// find the column that this cell belongs to
DataGridBoundColumn col =
cell.Column as DataGridBoundColumn;

// find the property that this column is bound to
Binding binding = col.Binding as Binding;
string boundPropertyName = binding.Path.Path;

// find the object that is related to this row
object data = row.Item;

// extract the property value
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(data);

PropertyDescriptor property = properties[boundPropertyName];
if (property != null)
{
object value = property.GetValue(data);

return value;
}

return null;
}

private void DataGrid_KeyDown_1(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;

DependencyObject dep = (DependencyObject)e.OriginalSource;
//here we just find the cell got focused ...
//then we can use the cell key down or key up
// iteratively traverse the visual tree
while ((dep != null) && !(dep is DataGridCell) && !(dep is DataGridColumnHeader))
{
dep = VisualTreeHelper.GetParent(dep);
}

if (dep == null)
return;

if (dep is DataGridCell)
{
try
{
//cancel if datagrid in edit mode
maindg.CommitEdit();


//Check if selected cell is on first column and last row
if (maindg.CurrentColumn.DisplayIndex == 0)
{
DependencyObject dep1 = dep;
while ((dep1 != null) && !(dep1 is DataGridRow))
{
dep1 = VisualTreeHelper.GetParent(dep1);
}

DataGridRow row = dep1 as DataGridRow;

if (FindRowIndex(row) == maindg.Items.Count - 1)
{
if (ExtractBoundValue(row, dep as DataGridCell) == null)
{
btnSave.Focus();
return;
}
}
}
}
catch
{
maindg.CancelEdit();
}
//get current cell
DataGridCell cell = dep as DataGridCell;
//deselect current cell
cell.IsSelected = false;
//find next right cell
var nextCell = cell.PredictFocus(FocusNavigationDirection.Right);
//if next right cell null go for find next ro first cell
if (nextCell == null)
{
DependencyObject nextRowCell;
nextRowCell = cell.PredictFocus(FocusNavigationDirection.Down);
//if next row is null so we have no more row Return;
if (nextRowCell == null)
{
nextRowCell = dep;
while ((nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left) != null)
nextRowCell = (nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left);
//change current cell
maindg.CurrentCell = new DataGridCellInfo(nextRowCell as DataGridCell);
//change selected cell
(nextRowCell as DataGridCell).IsSelected = true;
return;
}
//we do this because we cant use FocusNavigationDirection.Next for function PredictFocus
//so we have to find it this way
while ((nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left) != null)
nextRowCell = (nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left);
//set new cell as next cell
nextCell = nextRowCell;
}

//change current cell
maindg.CurrentCell = new DataGridCellInfo(nextCell as DataGridCell);
//change selected cell
(nextCell as DataGridCell).IsSelected = true;
// start edit mode
maindg.BeginEdit();
}
//handl the default action of keydown
e.Handled = true;
}
}

最佳答案

你快到了。在 GotFocus() 上,只需将 CanUserAddRows 设置为 True。并在 LostFocus() 处理程序上将其设置为 False

由于当焦点在网格内移动时也会调用 LostFocus 处理程序,您可以检查属性 IsKeyboardFocusWithin 以了解焦点是否在网格内。

private void maindg_GotFocus(object sender, RoutedEventArgs e)
{
if (!maindg.CanUserAddRows)
{
maindg.CanUserAddRows = true;
}
}

private void maindg_LostFocus(object sender, RoutedEventArgs e)
{
if (!maindg.IsKeyboardFocusWithin && maindg.CanUserAddRows)
{
maindg.CanUserAddRows = false;
}
}

关于c# - 删除 DataGrid 中自动生成的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24589429/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com