首页 > 解决方案 > 单击按钮时向 DataGrid 添加新行

问题描述

我是 WPF 新手,在单击按钮时将新行添加到数据网格时遇到问题。我尝试了一些解决方案,但没有成功。

尝试过-如果我启用“CanUserAddRows =”True”,这给了我也出现在上排的按钮。我也不想要这种方法,因为我想在按钮单击时添加新行。

如果我使用“CanUserAddRows="True",我将附上新行的样子

<StackPanel Name="Decrypt_Vault">
                            <DataGrid  x:Name="gdDecryptVault" HorizontalAlignment="Left"  ColumnWidth="Auto" Margin="10,10,405,18"  AutoGenerateColumns="False" HorizontalGridLinesBrush="LightGray" VerticalGridLinesBrush="LightGray">

                                <DataGrid.Columns>
                                    <!--<DataGridTextColumn Header="Host" Binding="{Binding Path=Host}" Width="*" IsReadOnly="True" />-->
                                    <DataGridTemplateColumn Header="Host">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Path=Host}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=Host, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <!--<DataGridTextColumn Header="Login" Binding="{Binding Path=Login}" Width="*" IsReadOnly="True" />-->
                                    <DataGridTemplateColumn Header="Login">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Path=Login}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=Login, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <!--<DataGridTextColumn Header="Password" Binding="{Binding Path=Password}" Width="*" IsReadOnly="True"/>-->
                                    <DataGridTemplateColumn Header="Password" IsReadOnly="True">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                    <TextBlock Name="LinePassword" Text="{Binding Path=Password}" Visibility="{Binding Path=IsPasswordVisible, Converter={StaticResource BoolToVis}}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <DataGridTemplateColumn Header="Password Actions" IsReadOnly="True">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <DockPanel>
                                                    <Button  Click="bTogglePassword_Click" ToolTip="Toggle Password"
                                                        Name="bTogglePassword" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/button_login1.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                    <Button Click="bCopyToClipBoard_Click" ToolTip="Copy Password to clipboard"
                                                        Name="bCopyToClipBoard" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/Copy_icon.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                </DockPanel>
                                                <!--<TextBlock Text="{Binding Path=Password}"></TextBlock>-->
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>

                                    <!--<DataGridTextColumn Header="Items" Binding="{Binding Path=Project.Name}" Width="*" IsReadOnly="True"/>-->
                                    <DataGridTemplateColumn Header="Items" Width="100">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Path=Project.Name}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=Project.Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <!--<DataGridTextColumn Header="Created by" Binding="{Binding Path=CreatedBy}" Width="*" IsReadOnly="True"/>-->
                                    <DataGridTemplateColumn Header="Created By" >
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Path=CreatedBy}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=CreatedBy, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <!--<DataGridTextColumn Header="Notes" Binding="{Binding Path=Notes}" Width="*" IsReadOnly="True"/>-->
                                    <DataGridTemplateColumn Header="Notes" Width="100">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Path=Notes}"></TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <TextBox Background="Aquamarine" Text="{Binding Path=Notes, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                    <DataGridTemplateColumn Header="Actions" Width="100">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <DockPanel>
                                                    <!--<Button Content="Edit" Click="EditVaultLine"/>-->
                                                    <Button  Click="EditVaultLine" ToolTip="Edit"
                                                        Name="Edit" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/edit.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                    <Button  Click="DeleteVaultLine" ToolTip="Delete"
                                                        Name="Delete" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/delete.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                </DockPanel>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <DockPanel >
                                                    <Button  Click="SaveEditedVaultLine" ToolTip="Save"
                                                        Name="Save" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/save2.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                    <Button  Click="CancelEditVaultLine" ToolTip="Cancel"
                                                        Name="Cancel" Visibility="Visible"  Height="30" Width="30" >
                                                        <Image Source="/Images/erase.png" Stretch="Fill" Height="30" Width="30"/>
                                                    </Button>
                                                </DockPanel>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                    </DataGridTemplateColumn>

                                </DataGrid.Columns>
                            </DataGrid>
                        </StackPanel>



My .CS code to Bind data in Data-Grid
 var result = weekTaskView.getVaultRecordLines();
                List<VaultRecordLine> list = new List<VaultRecordLine>();
                foreach (var item in result.Entities)
                {
                    VaultRecordLine vrl = new VaultRecordLine();

                    if (item.Attributes.Contains("createdby"))
                    {
                        vrl.CreatedBy = item.Attributes["createdby"].ToString();
                    }
                    if (item.Attributes.Contains("new_account"))
                    {
                        vrl.Host = item.Attributes["new_account"].ToString();
                    }
                    if (item.Attributes.Contains("new_login"))
                    {
                        vrl.Login = item.Attributes["new_login"].ToString();
                    }
                    if (item.Attributes.Contains("new_password"))
                    {
                        vrl.Password = item.Attributes["new_password"].ToString();
                    }
                    if (item.Attributes.Contains("new_vaultid"))
                    {
                        vrl.Id = new Guid(item.Attributes["new_vaultid"].ToString());
                    }

                    list.Add(vrl);
                }
                gdDecryptVault.ItemsSource = list;

要求 - 当我单击“添加新行按钮”时,我需要一个处于可编辑模式的新行,以便用户可以填写数据。我还需要在行末尾的“保存”和“取消”按钮来保存该数据或分别“取消”它。

标签: c#wpfdata-bindingdatagrid

解决方案


我制作了一个小示例应用程序来向您展示如何将项目添加到 DataGrid。

您的 DataGrid 应该绑定到ObservableCollection<T>其中 T 是您的 DataClass 的类型。then的定义DataGrid类似于:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}" CanUserAddRows="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Host" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock VerticalAlignment="Center" Margin="4,2" Text="{Binding Host, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Login" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock VerticalAlignment="Center" Margin="4,2" Text="{Binding Login, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Password" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock VerticalAlignment="Center" Margin="4,2" Text="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

然后,您必须Button将新行添加到 DataGrid 的 ItemsSource。Button可以看起来像:

<Button Grid.Row="1" Content="Add item" Command="{Binding AddItemCommand}"/>

在您的 c#-Code 中,您的 Button 的命令绑定到的 AddItemCommand 如下所示:

private ICommand addItemCommand;
public ICommand AddItemCommand
{
    get { return addItemCommand ?? (addItemCommand = new RelayCommand(AddItem)); }
}

private void AddItem(object obj)
{
    Items.Add(new MyItem());
}

绑定到的ObservableCollection<T>地方如下所示:DataGrid

private ObservableCollection<MyItem> items;

public ObservableCollection<MyItem> Items
{
    get { return items ?? (items = new ObservableCollection<MyItem>()); }
}

因此,现在当您按下按钮时,将执行 AddItemCommand,这将向 DataGrid 的 ItemsSource 添加一个新项目。


RelayCommand 是 -interface 的实现ICommand。所以你不必使用点击事件。因此,您可以将 XAML 定义(视图)与 C# 逻辑(视图模型)分离。这是使用 MVVM 模式的重要一步。

public class RelayCommand : ICommand
{
    private readonly Action<object> execute;
    private readonly Predicate<object> canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        if(execute == null)
            throw new ArgumentException(nameof(execute));
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute == null || canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        execute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

如果你是 WPF 的新手,你应该看看 MVVM-Pattern。真的很有用


推荐阅读