在编辑时修改WPF DataGrid中的用户控件

时间:2014-04-03 20:49:04

标签: wpf wpfdatagrid

我是WPF的新手,并试图解决一个看似简单的问题。

我需要设计一个数据表并允许用户编辑它。当用户开始编辑单元格时,我需要在最右边的列[OK]和[取消]中显示一组按钮,以接受或取消更改。当用户不编辑单元格时,应显示[删除]按钮以供用户删除该行。

我写了一个自定义控件,根据自定义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}
                              }
            );
    }

非常感谢您提供任何信息和提示!

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

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