Marschal
Marschal

Reputation: 183

WPF edit autogenerated column header text

I'm using a WPF DataGrid to display DataTable's. I need to be able to edit this bound DataTables (Two-Way Binding).

I'm using the DataGrid as followed:

<DataGrid SelectionUnit="CellOrRowHeader" IsReadOnly="False" AutoGenerateColumns="True" ItemsSource="{Binding Path=SelectedItem.BindableContent, FallbackValue={x:Null}}" />

The Problem I have, the user can't edit the ColumnHeader's like cell content or rows. The Screenshot below illustrates that porblem. The only thing I can do is sort the columns. Is there a way to edit the column headers too, for example when the user clicks twice, or presses F2.

Maybe some Style' or a HeaderTemplate will do the job? I have already tried some styles and control templates I've found around the internet, but without any success.

Editable Cells, but not editable Col Headers

EDIT:

I managed to display the column headers in a TextBox (and not in a TextBlock) within the AutogeneratingTextcolumn event handler:

Column Header Text in TextBox

private void _editor_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) {
  // First: create and add the data template to the parent control
  DataTemplate dt = new DataTemplate(typeof(TextBox));
  e.Column.HeaderTemplate = dt;

  // Second: create and add the text box to the data template
  FrameworkElementFactory txtElement =
      new FrameworkElementFactory(typeof(TextBox));
  dt.VisualTree = txtElement;

  // Create binding
  Binding bind = new Binding();
  bind.Path = new PropertyPath("Text");
  bind.Mode = BindingMode.TwoWay;

  // Third: set the binding in the text box
  txtElement.SetBinding(TextBox.TextProperty, bind);
  txtElement.SetValue(TextBox.TextProperty, e.Column.Header);
}             

But I couldn't manage to set the binding correctly, if i edit the Text in the TextBoxes, it does not change the text in the Column.Header-Property (which is auto-generated by a binding to a DataTable like explained above).

Upvotes: 0

Views: 944

Answers (1)

You forgot to set the source of your binding and you mustn't set the value after the registration of the binding. The correct code would be the following:

private void asdf_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataTemplate dt = new DataTemplate(typeof(TextBox));
        e.Column.HeaderTemplate = dt;

        FrameworkElementFactory txtElement =
            new FrameworkElementFactory(typeof(TextBox));
        dt.VisualTree = txtElement;

        Binding bind = new Binding();
        bind.Path = new PropertyPath("Header");
        bind.Mode = BindingMode.TwoWay;
        // set source here
        bind.Source = e.Column;

        txtElement.SetBinding(TextBox.TextProperty, bind);
        // You mustn't set the value here, otherwise the binding doesn't work
        // txtElement.SetValue(TextBox.TextProperty, e.Column.Header);
    }

Additionally you must change the binding property to Header, because you are adding the binding to the text property of the TextBox.

Upvotes: 1

Related Questions