C# WinForms 上是否有任何方法可以仅在某些单元格中添加按钮,以便它们(按钮)成为单元格的一部分?并添加该按钮的处理程序。 这需要将特定单元格的值插入到另一种形式中。但它不必执行表中的所有单元格。 就像图片上一样。
(来源: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;
}
}
结果:
- 请注意,我正在使用 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/