c# - 向 datagridView 中的某些单元格添加按钮

标签 c# winforms button datagridview custom-cell

C# WinForms 上是否有任何方法可以仅在某些单元格中添加按钮,以便它们(按钮)成为单元格的一部分?并添加该按钮的处理程序。 这需要将特定单元格的值插入到另一种形式中。但它不必执行表中的所有单元格。 就像图片上一样。

already added buttons
(来源:snag.gy)

最佳答案

将此作为答案发布,因为 OP 要求这样做:

这是我的 WPF 对此的看法:

<Window x:Class="MiscSamples.DataGridCustomCells"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MiscSamples"
        Title="DataGridCustomCells" Height="300" Width="300">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisibiltyConverter"/>
        <Style TargetType="DataGridCell" x:Key="ButtonCell">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <!-- ControlTemplate obtained with Expression Blend -->
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                                Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <Grid>
                                <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                <Button Height="16" Width="16" VerticalAlignment="Top" HorizontalAlignment="Right"
                                        Visibility="{Binding (local:DataGridParameters.ShowButton), 
                                                             RelativeSource={RelativeSource TemplatedParent},
                                                             Converter={StaticResource BoolToVisibiltyConverter}}"
                                        Command="{Binding CellButtonCommand, RelativeSource={RelativeSource AncestorType=Window}}"
                                        CommandParameter="{Binding (local:DataGridParameters.ButtonValue), RelativeSource={RelativeSource TemplatedParent}}"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>


    <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding LastName}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell" BasedOn="{StaticResource ButtonCell}">
                        <Setter Property="local:DataGridParameters.ShowButton" Value="{Binding DataContext.ShowButtonOnLastName, RelativeSource={RelativeSource Self}}"/>
                        <Setter Property="local:DataGridParameters.ButtonValue" Value="{Binding DataContext.LastName, RelativeSource={RelativeSource Self}}"/>
                    </Style>
                </DataGridTextColumn.CellStyle>    
            </DataGridTextColumn>

            <DataGridTextColumn Binding="{Binding FirstName}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell" BasedOn="{StaticResource ButtonCell}">
                        <Setter Property="local:DataGridParameters.ShowButton" Value="{Binding DataContext.ShowButtonOnFirstName, RelativeSource={RelativeSource Self}}"/>
                        <Setter Property="local:DataGridParameters.ButtonValue" Value="{Binding DataContext.FirstName, RelativeSource={RelativeSource Self}}"/>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

背后代码:

public partial class DataGridCustomCells : Window
    {
        public ICommand CellButtonCommand { get; set; }

        public DataGridCustomCells()
        {
            CellButtonCommand = new Command<object>(OnCellCommandExecuted){IsEnabled = true};

            InitializeComponent();

            DataContext = new List<DataGridSampleData>
                {
                    new DataGridSampleData() {LastName = "Simpson", FirstName = "Homer", ShowButtonOnFirstName = true},
                    new DataGridSampleData() {LastName = "Szyslak", FirstName = "Moe", ShowButtonOnLastName = true},
                    new DataGridSampleData() {LastName = "Gumble", FirstName = "Barney", ShowButtonOnFirstName = true},
                    new DataGridSampleData() {LastName = "Burns", FirstName = "Montgomery", ShowButtonOnLastName = true},
                };
        }

        private void OnCellCommandExecuted(object parameter)
        {
            MessageBox.Show("Command Executed: " + parameter);
        }
    }

示例数据类:

public class DataGridSampleData //TODO: Implement INotifyPropertyChanged
{
    public string LastName { get; set; }

    public string FirstName { get; set; }

    public bool ShowButtonOnFirstName { get; set; }

    public bool ShowButtonOnLastName { get; set; }
}

帮助类:

public static class DataGridParameters
{
    public static readonly DependencyProperty ShowButtonProperty = DependencyProperty.RegisterAttached("ShowButton", typeof(bool), typeof(DataGridParameters));

    public static void SetShowButton(DependencyObject obj, bool value)
    {
        obj.SetValue(ShowButtonProperty, value);
    }

    public static bool GetShowButton(DependencyObject obj)
    {
        return (bool) obj.GetValue(ShowButtonProperty);
    }

    public static readonly DependencyProperty ButtonValueProperty = DependencyProperty.RegisterAttached("ButtonValue", typeof(object), typeof(DataGridParameters));

    public static void SetButtonValue(DependencyObject obj, object value)
    {
        obj.SetValue(ButtonValueProperty, value);
    }

    public static object GetButtonValue(DependencyObject obj)
    {
        return obj.GetValue(ButtonValueProperty);
    }
}

通用基本 DelegateCommand:

    //Dead-simple implementation of ICommand
    //Serves as an abstraction of Actions performed by the user via interaction with the UI (for instance, Button Click)
    public class Command<T>: ICommand
    {
        public Action<T> Action { get; set; }

        public void Execute(object parameter)
        {
            if (Action != null && parameter is T)
                Action((T)parameter);
        }

        public bool CanExecute(object parameter)
        {
            return IsEnabled;
        }

        private bool _isEnabled;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                _isEnabled = value;
                if (CanExecuteChanged != null)
                    CanExecuteChanged(this, EventArgs.Empty);
            }
        }

        public event EventHandler CanExecuteChanged;

        public Command(Action<T> action)
        {
            Action = action;
        }
    }

结果:

enter image description here

  • 请注意,我正在使用 Attached Properties在现有 DataGridCell 中启用额外行为
  • 此外,我正在使用 DelegateCommand让这些按钮全部重定向到相同的底层逻辑。
  • 我的示例中没有一行代码处理任何 UI 元素。一切都是通过数据绑定(bind)完成的。这就是在 WPF 中编码的方式。
  • 这是一个非常基本且初级的示例。您可以通过定义RowViewModel<TEntity>来创建更具可扩展性的解决方案。其中每个单元格值都包含在 CellViewModel<TValue> 中定义按钮功能以及是否显示按钮等等。
  • 没有“所有者抽奖”,没有 P/Invoke,没有可怕的代码隐藏攻击。
  • WPF 岩石。只需将我的代码复制到 File -> New Project -> WPF Application 中即可并亲自查看结果。

关于c# - 向 datagridView 中的某些单元格添加按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16762106/

相关文章:

c# - C# 上的 MySQL 连接超时

c# - 使用用户实现的 zip 函数合并不同大小的数组

c# - 如何为按钮创建自定义双击事件

html - 按钮不会停留在背景图片上

css - 中心 CSS 按钮宽度自动

ios - 根据按钮选择状态将无法识别的选择器发送到实例

c# - 如何通过使用C#正则表达式进行Elasticsearch将json格式的句子转换为另一句?

c# - 如果做两件事,是否可以将 foreach 操作转换为 LINQ?

c# - 在面板内的控件之上绘图 (C# WinForms)

c# - 如何访问 DevExpress XtraTreeList 中绑定(bind)到节点的对象?