为什么WPF Datagrid SelectionUnit =“Cell”导致禁用DataGridTemplateColumn控件?

时间:2012-06-15 17:39:55

标签: wpf datagrid datatemplate wpfdatagrid datagridtemplatecolumn

这看起来有点古怪:我有一个带有按钮列的Datagrid,当单击该行的按钮时会删除该行。但是,如果我设置Datagrid SelectionUnit =“Cell”,那么按钮列将被禁用,我不能再单击该按钮。

有谁能告诉我为什么会这样,以及如何避免列的禁用行为?

以下是重新创建问题的XAML - add&删除SelectionUnit =“Cell”以查看行为的变化

<Window.Resources>
    <local:DummyCollection x:Key="stringCollection">
        <local:Dummy x="1" y="2" z="3" />
        <local:Dummy x="4" y="5" z="6" />
        <local:Dummy x="7" y="8" z="9" />
    </local:DummyCollection>
</Window.Resources>

<StackPanel>
    <DataGrid ItemsSource="{Binding Source={StaticResource stringCollection}}" AutoGenerateColumns="False" SelectionUnit="Cell">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="a" Binding="{Binding Path=x}" Header="a" />
            <DataGridTextColumn x:Name="b" Binding="{Binding Path=y}" Header="b" />
            <DataGridTextColumn x:Name="c" Binding="{Binding Path=z}" Header="c" />
            <DataGridTemplateColumn  x:Name="deleteButtonColumn" Header="D">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Command="Delete" >D</Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</StackPanel>

将此添加到后面的Window代码中:

public class Dummy
{
    public string x { get; set; }
    public string y { get; set; }
    public string z { get; set; }
}
public class DummyCollection : ObservableCollection<Dummy> { }

1 个答案:

答案 0 :(得分:1)

我认为设置SelectionUnit="Cell"SelectionUnit="FullRow"之间没有区别。两者都不起作用,因为命令属性没有绑定到命令。

您应该将按钮的Command属性绑定到ICommand的实现。 以下是使用MVVM Light的RelayCommand基于您的代码的示例。

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>
<StackPanel>
    <DataGrid ItemsSource="{Binding Items}" 
              AutoGenerateColumns="False" SelectionUnit="Cell">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="a" Binding="{Binding Path=x}" Header="a" />
            <DataGridTextColumn x:Name="b" Binding="{Binding Path=y}" Header="b" />
            <DataGridTextColumn x:Name="c" Binding="{Binding Path=z}" Header="c" />
            <DataGridTemplateColumn  x:Name="deleteButtonColumn" Header="D">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Command="{Binding Path=DataContext.Delete, 
                                RelativeSource={RelativeSource Mode=FindAncestor, 
                                AncestorType={x:Type DataGrid}}}" 
                                CommandParameter="{Binding}">D</Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</StackPanel>

public class Dummy
{
    public string x { get; set; }
    public string y { get; set; }
    public string z { get; set; }

    public override string ToString()
    {
        return string.Format("x:{0}, y:{1}, z:{2}", x, y, z);
    }
}

public class DummyCollection : ObservableCollection<Dummy> { } 

public class ViewModel
{
    public ViewModel()
    {
        Items = new DummyCollection
            {
                new Dummy {x = "1", y = "2", z = "3"},
                new Dummy {x = "4", y = "5", z = "6"},
                new Dummy {x = "7", y = "8", z = "9"},
            };

        Delete = new RelayCommand<Dummy>(DeleteItem);
    }

    public ICommand Delete { get; private set; }

    private void DeleteItem(Dummy item)
    {
        Debug.WriteLine("Delete item, " + item);
    }

    public DummyCollection Items { get; private set; }
}