C# WinForms 有没有办法只在某些单元格中添加按钮,以便它们(按钮)是单元格的一部分?并为此按钮添加处理程序。这需要将特定单元格的值插入另一种形式。但它不必对表格中的所有单元格进行处理。就像图片上的一样。
问问题
1397 次
1 回答
2
将其发布为答案,因为 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;
}
}
结果:
- 请注意,我正在使用附加属性来启用现有
DataGridCell
s 中的额外行为。 - 此外,我使用DelegateCommand将这些按钮全部重定向到相同的底层逻辑。
- 在我的示例中,没有一行代码可以处理任何 UI 元素。一切都是通过 DataBinding 完成的。这就是您在 WPF 中编码的方式。
- 这是一个非常基本和基本的示例。
RowViewModel<TEntity>
您可以通过定义每个单元格值包含在CellViewModel<TValue>
定义按钮功能以及是否显示按钮等的位置来创建更具可扩展性的解决方案。 - 没有“所有者抽奖”,没有 P/Invoke,没有可怕的代码隐藏黑客。
- WPF 摇滚。只需将我的代码复制到 a 中
File -> New Project -> WPF Application
,然后自己查看结果。
于 2013-07-22T15:53:24.493 回答