WPF DataGrid中的新项占位符消失

时间:2011-08-19 19:26:14

标签: wpf datagrid

我的DataGrid中有一个无效的新项目行。我将焦点更改为另一个元素,它清除了此数据网格的后备集合。这会导致新项占位符(数据网格底部的空行)消失。

如何重新出现?

2 个答案:

答案 0 :(得分:1)

如果您正在清除集合,使得DataGrid根本没有显示任何行,那么听起来您正面临着与此处讨论的相同的问题:

WPF DataGrid: Blank Row Missing

基本上,问题是DataGrid不知道它绑定到哪个对象类型,因此无法为新项占位符生成列(例如,它不知道是否提供空白用于个人姓名的单元格,订单的交付日期或宠物的头发颜色等。 上面讨论的讨论中的一个答案是添加一个虚拟对象然后删除它 - 这对我有用。

答案 1 :(得分:1)

我无法制作"删除项目/重新插入项目"修复我的应用程序的工作。在解决此问题时,我注意到DataGrid的内置DeleteCommand将1)删除所选行,即使对于具有绑定ItemsSource的DataGrid也是如此2)如果在行上触发DeleteCommand,则不会使NewItemPlaceHolder行消失它处于编辑模式!

这是我的应用程序的DataGrid,它有一个DataGridTemplateColumn,其中包含一个使用内置DeleteCommand的按钮。 注意:必须选择该行才能启用该按钮,然后单击该按钮将删除该行。我确定您可以继承DataGrid的OnCanExecuteDelete并修改此行为。

<local:MyDataGrid           
ItemsSource="{Binding Companies}"           
AutoGenerateColumns="False" 
RowHeaderWidth="20"
x:Name="dg">
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Delete">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Button Content="X" 
                        Command="DataGrid.DeleteCommand"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
</DataGrid.Columns>

作为奖励,这里的子类DataGrid给了我同样的问题(或者是 - 这是一个老帖子)。它包含代码I borrowed from another StackOverflow user,可以对任何DataGridCell进行单击编辑。

public class MyDataGrid : DataGrid
{
    public MyDataGrid()
    {
        this.GotFocus += DataGrid_CellGotFocus;                             
    }

    protected override void OnExecutedDelete(ExecutedRoutedEventArgs e)
    {
        // Temporarily remove the GotFocus eventhandler to prevent
        // the datagrid from firing BeginEdit after a row is deleted.
        this.GotFocus -= DataGrid_CellGotFocus;                                         
        base.OnExecutedDelete(e);
        this.GotFocus += DataGrid_CellGotFocus;                             
    }

    private void DataGrid_CellGotFocus(object sender, RoutedEventArgs e)
    {
        // Lookup for the source to be DataGridCell
        if (e.OriginalSource.GetType() == typeof(DataGridCell))
        {
            // Starts the Edit on the row;
            DataGrid grd = (DataGrid)sender;
            grd.BeginEdit(e);

            //Control control = e.OriginalSource as DataGridCell;
            Control control = GetFirstChildByType<Control>(e.OriginalSource as DataGridCell);
            if (control != null)
            {                   
                control.Focus();
            }
        }
    }

    /// <summary>
    /// Returns the first visual tree child item matching T.
    /// </summary>
    /// <param name="prop"></param>
    /// <returns></returns>
    private T GetFirstChildByType<T>(DependencyObject prop) where T : DependencyObject
    {
        // Begin a loop thru all visual tree items for the DependencyObject arg.
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(prop); i++)
        {
            // Loop to the next visual tree item if the current item is null.
            DependencyObject child = VisualTreeHelper.GetChild((prop), i) as DependencyObject;
            if (child == null)
                continue;

            // Try casting the current item to T. If the cast works, return the visual tree
            // item as T. 
            T castedProp = child as T;
            if (castedProp != null)
                return castedProp;

            // If this code line is reached, the cast failed. Recursively call this method.
            castedProp = GetFirstChildByType<T>(child);

            if (castedProp != null)
                return castedProp;
        }
        // If this code line is reached, no visual tree items in prop match T. Return null.
        return null;
    }   
}