问题
I have a DataGrid which I initialized with one list item from an ObservableCollection. I would like to allow the user to complete the rest of the datagrid. I have CanUserAddRows=true; I have two textboxes which are enabled/disabled with checkboxes. After filling out the second row, it will not add additional rows unless you double click in one of the cells next to a checkbox(not in the checkbox). It will then put all the number values to 0 and empty any strings and move the current row values to the next row. I would ideally like to add a new empty row by clicking a button, but would settle for a new row by pushing enter.
<Window x:Class="Tourny2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Tourny2"
mc:Ignorable="d"
Title="Structure Entry" Height="300" Width="804" FontFamily="Verdana" FontSize="16">
<Grid Margin="0,0,0,0">
<DataGrid x:Name="dataGrid" CanUserAddRows="True" HeadersVisibility="Column" AutoGenerateColumns="False" Background="#FFCEE8E5" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" CanUserSortColumns="False" CanUserReorderColumns="False" FrozenColumnCount="1" ClipToBounds="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Levels">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate >
<TextBox x:Name="levelEntry" Width="Auto" Text="{Binding LevelName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Use Antes" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="useAntes" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,5,6" Checked="useAntes_Checked" Unchecked="useAntes_Unchecked" IsChecked="{Binding IsActive}"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="EnterAntes" Header="Antes">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="antesEntry" Width="Auto" IsEnabled="False" KeyDown="antesEntry_KeyDown" Text="{Binding Antes}" Loaded="antesEntry_Loaded"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Small Blind">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="SBEntry" Width="Auto" KeyDown="SBEntry_KeyDown" Text="{Binding SmallBlind}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Big Blind">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="BBEntry" Width="Auto" KeyDown="BBEntry_KeyDown" Text="{Binding BigBlind}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Level Time">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="levelTimeEntry" Width="Auto" KeyDown="levelTime_KeyDown" Text="{Binding LevelTime}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="List Games" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="listGames" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,5,6" Checked="listGames_Checked" Unchecked="listGames_Unchecked" IsChecked="{Binding IsActive}"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Current Game">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="gameEntry" Width="Auto" IsEnabled="False" Text="{Binding CurrentGame}" Loaded="gameEntry_Loaded"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button x:Name="SaveStructure" Content="Save" HorizontalAlignment="Left" Margin="719,0,0,235" VerticalAlignment="Bottom" Width="75" Click="button_Click" Height="35"/>
</Grid>
namespace Tourny2
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private TextBox antesEntry;
private TextBox gameEntry;
public Window1()
{
InitializeComponent();
ObservableCollection<Level> levels = new ObservableCollection<Level>();
levels.Add(new Level() { LevelName = "Level 1", UseAntes = false, SmallBlind = 25, BigBlind = 50, LevelTime = 20, ListGames = false } );
dataGrid.ItemsSource = levels;
}
private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void antesEntry_Loaded(object sender, RoutedEventArgs e)
{
antesEntry = (sender as TextBox);
}
private void gameEntry_Loaded(object sender, RoutedEventArgs e)
{
gameEntry = (sender as TextBox);
}
private void useAntes_Checked(object sender, RoutedEventArgs e)
{
CheckBox c = (sender as CheckBox);
if (c.IsChecked == true)
{
antesEntry.IsEnabled = true;
}
}
private void listGames_Checked(object sender, RoutedEventArgs e)
{
CheckBox c = (sender as CheckBox);
if (c.IsChecked == true)
{
gameEntry.IsEnabled = true;
}
}
private void useAntes_Unchecked(object sender, RoutedEventArgs e)
{
CheckBox c = (sender as CheckBox);
if (c.IsChecked == false)
{
antesEntry.IsEnabled = false;
}
}
private void listGames_Unchecked(object sender, RoutedEventArgs e)
{
CheckBox c = (sender as CheckBox);
if (c.IsChecked == false)
{
gameEntry.IsEnabled = false;
}
}
private void antesEntry_KeyDown(object sender, KeyEventArgs e) //allow only digits (keyboard and numbers pad)
{ //tab and backspace to be entered in antes
int key = (int)e.Key;
e.Handled = !(key >= 34 && key <= 43 ||
key >= 74 && key <= 83 || key == 2);
if (e.Key == Key.Tab)
{
e.Handled = false;
}
}
private void SBEntry_KeyDown(object sender, KeyEventArgs e) //allow only digits (keyboard and numbers pad)
{ //tab and backspace to be entered in SB
int key = (int)e.Key;
e.Handled = !(key >= 34 && key <= 43 ||
key >= 74 && key <= 83 || key == 2);
if(e.Key == Key.Tab|| e.Key == Key.Enter)
{
e.Handled = false;
}
}
private void BBEntry_KeyDown(object sender, KeyEventArgs e) //allow only digits (keyboard and numbers pad)
{ //tab and backspace to be entered in BB
int key = (int)e.Key;
e.Handled = !(key >= 34 && key <= 43 ||
key >= 74 && key <= 83 || key == 2);
if (e.Key == Key.Tab)
{
e.Handled = false;
}
}
private void levelTime_KeyDown(object sender, KeyEventArgs e) //allow only digits (keyboard and numbers pad)
{
//tab,and backspace to be entered in Level Time
int key = (int)e.Key;
e.Handled = !(key >= 34 && key <= 43 ||
key >= 74 && key <= 83 || key == 2);
if (e.Key == Key.Tab||e.Key == Key.Enter)
{
e.Handled = false;
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
dataGrid.SelectAllCells();
dataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.ExcludeHeader;
ApplicationCommands.Copy.Execute(null, dataGrid);
dataGrid.UnselectAllCells();
String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
Clipboard.Clear();
using (StreamWriter file = new StreamWriter("..\\TestStructure.csv"))
{
file.WriteLine(result);
}
}
}
}
namespace Tourny2
{
public class Level : INotifyPropertyChanged
{
private string levelName = ""; //declare some fields
private bool useAntes = false;
private int antes;
private int smallBlind = 0;
private int bigBlind = 0;
private double levelTime = 0;
private bool listGames = false;
private string currentGame;
public string LevelName //create properties for the fields
{
get { return this.levelName; }
set
{
if (this.levelName != value)
{
this.levelName = value;
this.NotifyPropertyChanged("LevelName");
}
}
}
public bool UseAntes
{
get { return this.useAntes; }
set
{
if (this.useAntes != value)
{
this.useAntes = value;
this.NotifyPropertyChanged("UseAntes");
}
}
}
public int Antes
{
get { return (int)antes; }
set
{
if (this.antes != value)
{
this.antes = value;
this.NotifyPropertyChanged("Antes");
}
}
}
public int SmallBlind
{
get { return this.smallBlind; }
set
{
if (this.smallBlind != value)
{
this.smallBlind = value;
this.NotifyPropertyChanged("SmallBlind");
}
}
}
public int BigBlind
{
get { return this.bigBlind; }
set
{
if (this.bigBlind != value)
{
this.bigBlind = value;
this.NotifyPropertyChanged("BigBlind");
}
}
}
public double LevelTime
{
get { return this.levelTime; }
set
{
if (this.levelTime != value)
{
this.levelTime = value;
this.NotifyPropertyChanged("LevelTime");
}
}
}
public bool ListGames
{
get { return this.listGames; }
set
{
if (this.listGames != value)
{
this.listGames = value;
this.NotifyPropertyChanged("ListGames");
}
}
}
public string CurrentGame
{
get { return this.currentGame; }
set
{
if (this.currentGame != value)
{
this.currentGame = value;
this.NotifyPropertyChanged("CurrentGame");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public Level()
{
this.levelName = levelName;
this.useAntes = useAntes;
this.antes = antes;
this.smallBlind = smallBlind;
this.bigBlind = bigBlind;
this.levelTime = levelTime;
this.listGames = listGames;
this.currentGame = currentGame;
}
回答1:
You can add blank rows by adding the following codes to data grid key up event.
if(e.Key == Key.Enter)
{
AddNewRow();
}
Now, implement the AddNewRow method as below.
private void AddNewRow()
{
TestItemList.Add(new TestItem());
gvTest.ItemsSource = TestItemList;
}
Here you add blank rows by just press enter on the data grid. According to the previous answer, I declared Observable collection instance as global instance so simply adding the above-mentioned code you can add blank rows.
Hope this helps you.
来源:https://stackoverflow.com/questions/33555544/wpf-datagrid-will-only-allow-user-to-add-1-row