WPF如何让datagrid动态地将下一个对象添加到下一行而不是当前行?

时间:2015-11-17 03:15:22

标签: c# wpf datagrid

在WPF中我有一个按钮,当点击它时,应该向数据网格添加一个新的空行以供用户输入。问题是它用空字符串或0值覆盖当前行而不是开始新行。如何让它开始新的一行?我试图找到一种方法来改变焦点或在当前行上提交编辑并尝试找到增加行数的方法

<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="850" FontFamily="Verdana" FontSize="16" ResizeMode="CanMinimize">
<Grid Margin="0,0,0,0" ClipToBounds="True">
    <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" ClipboardContentBinding="{Binding LevelName}">
                <DataGridTemplateColumn.CellTemplate >
                    <DataTemplate >
                        <TextBox x:Name="levelEntry"  Width="Auto"  Text="{Binding LevelName}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Use Antes" ClipboardContentBinding="{Binding UseAntes}" >
                <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" ClipboardContentBinding="{Binding Antes}" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="antesEntry" Width="Auto" IsEnabled="False" KeyDown="antesEntry_KeyDown" Text="{Binding Antes, TargetNullValue=' '}" Loaded="antesEntry_Loaded"></TextBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Small Blind" ClipboardContentBinding="{Binding SmallBlind}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="SBEntry" Width="Auto" KeyDown="SBEntry_KeyDown" Text="{Binding SmallBlind}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Big Blind" ClipboardContentBinding="{Binding BigBlind}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="BBEntry" Width="Auto" KeyDown="BBEntry_KeyDown" Text="{Binding BigBlind}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Level Time" ClipboardContentBinding="{Binding LevelTime}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="levelTimeEntry" Width="Auto" KeyDown="levelTime_KeyDown"  Text="{Binding LevelTime}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="List Games" ClipboardContentBinding="{Binding ListGames}">
                <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" ClipboardContentBinding="{Binding CurrentGame}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="gameEntry" Width="Auto" IsEnabled="False"   Text="{Binding CurrentGame, TargetNullValue=' '}" Loaded="gameEntry_Loaded"></TextBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    <Button x:Name="SaveStructure" Content="Save" FontFamily="Verdana" HorizontalAlignment="Left" Margin="739,0,0,235" VerticalAlignment="Bottom" Width="95" Click="saveStructure_Click" Height="27" ClipToBounds="True"/>
    <Button x:Name="LoadStructure" Content="Load" FontFamily="Verdana" HorizontalAlignment="Left" Margin="739,0,0,206" VerticalAlignment="Bottom" Width="95" Click="loadStructure_Click" Height="27" ClipToBounds="True"/>
    <Button x:Name="AddLevel" Content="Add Level" FontFamily="Verdana"  HorizontalAlignment="Left" Margin="739,0,0,177" VerticalAlignment="Bottom" Width="95" Height="27" Click="addLevel_Click" ClipToBounds="True"/>
    <Button x:Name="AddBreak" Content="Add Break" FontFamily="Verdana"  HorizontalAlignment="Left" Margin="739,0,0,148" VerticalAlignment="Bottom" Width="95" Height="27" Click="addBreak_Click" ClipToBounds="True"/>
</Grid>

namespace Tourny2
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
    private TextBox antesEntry;        
    private TextBox gameEntry;
    ObservableCollection<Level> levels = new ObservableCollection<Level>();
    public Window1()
    {
        InitializeComponent();


        //levels.Add(new Level() { LevelName = "Level 1", UseAntes = false, SmallBlind = 25, BigBlind = 50, LevelTime = 20, ListGames = false } );
        dataGrid.ItemsSource = levels;
    }

    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.Key == Key.Enter)
        {
            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.Key == Key.Enter)
        {
            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 saveStructure_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();
        SaveFileDialog dialog = new SaveFileDialog();
        if (dialog.ShowDialog() == true)
        {
            using (StreamWriter file = new StreamWriter("..\\"))
            {
                file.WriteLine(result);
            }
        }
    }

    public void addLevel_Click(object sender, RoutedEventArgs e)
    {            
        AddNewRows(levels);            

    }

    private void AddNewRows(ObservableCollection<Level> levels)
    {
       // int rowCount = dataGrid.Items.Count;

        levels.Add(new Level());
    }

    private void addBreak_Click(object sender, RoutedEventArgs e)
    {
        AddNewBreak(levels);
    }

    private void AddNewBreak(ObservableCollection<Level> levels)
    {
        levels.Add(new Level() { LevelName = "Break", UseAntes = false, SmallBlind = 0, BigBlind = 0});
    }

    private void loadStructure_Click(object sender, RoutedEventArgs e)
    {            
        using (StreamReader reader = new StreamReader("..\\TestStructure.csv"))
        {
            while (true)
            {
                string line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                levels.Add(new Level(line));
            }
        }  
        // ... Use ItemsSource.            
       dataGrid.ItemsSource = levels;
       //dataGrid = sender as DataGrid;
    }
  }        
}

1 个答案:

答案 0 :(得分:0)

此处的问题是您在行中输入的内容未在您的收藏中填充level

因此,您可以创建一个ViewModel并实现INotifyPropertyChanged之类的

public ViewModel : INotifyPropertyChanged
{

        private ObservableCollection<Level> mLevels;

        public ObservableCollection<Level> Levels
        {
            get
            {
                if (mLevels == null)
                {
                    mLevels = new ObservableCollection<Level>();
                }
                return mLevels;
            }
            set
            {
                mLevels = value;
                OnPropertyChanged("Levels");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
}

在你的Xaml中

<DataGrid ItemsSource="{Binding Levels,Mode=TwoWay}">