在编辑时修改 WPF DataGrid 中的用户控件
Posted
技术标签:
【中文标题】在编辑时修改 WPF DataGrid 中的用户控件【英文标题】:Modifying user control in WPF DataGrid on edit 【发布时间】:2014-05-15 22:26:38 【问题描述】:我是 WPF 的新手,在尝试解决一个看似简单的问题时遇到了困难。
我需要设计一个数据表并允许用户对其进行编辑。当用户开始编辑单元格时,我需要在最右边的列 [OK] 和 [Cancel] 中显示一组按钮来接受或取消更改。当用户不编辑单元格时,应显示 [Delete] 按钮供用户删除行。
我编写了一个自定义控件,该控件将根据自定义 IsInEditMode 属性显示 [OK][Cancel] 或单个 [Delete] 按钮。
public partial class RowEditControl : UserControl
public static DependencyProperty
IsInEditModeProperty = DependencyProperty.Register( "IsInEditMode",
typeof(bool),
typeof(RowEditControl),
new FrameworkPropertyMetadata(OnEditModeChanged));
private static void OnEditModeChanged(DependencyObject aD, DependencyPropertyChangedEventArgs aE)
//depending on the value show [Delete] or [Ok][Cancel] buttons
当用户开始编辑单元格时,我需要以某种方式设置 IsInEditMode。我一直在寻找整个 msdn 和这个论坛的示例/方法,但找不到任何东西。
我像这样以编程方式将自定义控件添加到最后一列:
mwTagList.Columns[1].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
var fRowEditTemplate = new FrameworkElementFactory(typeof (RowEditControl));
fRowEditTemplate.AddHandler(
RowEditControl.DeleteClickedEvent,
new RoutedEventHandler(OnDeleteRowBtn)
);
fRowEditTemplate.AddHandler(
RowEditControl.OkClickedEvent,
new RoutedEventHandler(OnRowEditOk));
fRowEditTemplate.AddHandler(
RowEditControl.CancelClickedEvent,
new RoutedEventHandler(OnRowEditCancel));
mwTagList.Columns.Add(
new DataGridTemplateColumn()
Header = "Delete Row",
CellTemplate = new DataTemplate() VisualTree = fRowEditTemplate
);
非常感谢您提供的任何信息和提示!
【问题讨论】:
【参考方案1】:我使用样式解决了这个问题:
<Style x:Key="MwControlCellStyle" TargetType="x:Type notesList:RowEditControl">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!-- find DataGridRow parent object and trigger if it is in editing mode -->
<Condition Binding="Binding RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type DataGridRow, Path=IsEditing" Value="True"></Condition>
</MultiDataTrigger.Conditions>
<Setter Property="IsInEditMode" Value="True"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
【讨论】:
【参考方案2】:DataGridRow 上有一个 IsEditing 依赖属性,因此您可以使用 XAML 和几个转换器来执行此操作。 XAML 的主要部分如下所示
<Window.Resources>
<viewModel:BooleanVisibleConverter x:Key="boolVisConv"/>
<viewModel:InverseBooleanVisibleConverter x:Key="invBoolVisConv"/>
<DataTemplate x:Key="DataGridButtonsTemplate">
<StackPanel >
<Button Content="Delete" Visibility ="Binding IsEditing, Mode=OneWay, Converter=StaticResource invBoolVisConv, RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=DataGridRow"/>
<Button Content="OK" Visibility="Binding IsEditing, Mode=OneWay, Converter=StaticResource boolVisConv,RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=DataGridRow"/>
<Button Content="Cancel" Visibility="Binding IsEditing, Mode=OneWay, Converter=StaticResource boolVisConv,RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=DataGridRow"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<DataGrid Grid.Row="1" ItemsSource="Binding MyData" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="Binding FirstField" Header="First Property"></DataGridTextColumn>
<DataGridTextColumn Binding="Binding SecondField" Header="Second Property"></DataGridTextColumn>
<DataGridTextColumn Binding="Binding ThirdField" Header="Third Property"></DataGridTextColumn>
<DataGridTemplateColumn Header="Control" CellTemplate="StaticResource DataGridButtonsTemplate"></DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
这里有一个示例转换器,显然你需要其中两个,第二个将返回值反转
[ValueConversion(typeof(bool), typeof(Visibility))]
public class BooleanVisibleConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
if (targetType != typeof(Visibility))
throw new InvalidOperationException("The target must be a System.Windows.Visibility");
return ((bool)value)? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
throw new NotSupportedException();
您需要确定按下的是哪个按钮,因为每行都有一个。这里有一些关于如何做到这一点的想法
WPF DataGrid - Button in a column, getting the row from which it came on the Click event handler
【讨论】:
谢谢!我使用上述样式解决了这个问题,但这看起来也很酷。这也是如何使用转换器的一个很好的例子,我是 WPF 新手,从未使用过它们。以上是关于在编辑时修改 WPF DataGrid 中的用户控件的主要内容,如果未能解决你的问题,请参考以下文章