Anya Hope
Anya Hope

Reputation: 1361

Bind to one column of datagrid and apply style

I have a WPF datagrid which is bound to a datatable using MVVM. There are several columns in this datatable, one of which is a nullable boolean. When the datagrid is rendered, the boolean column (containing mostly nulls) shows block-filled check boxes and looks awful:

Current: Nullable text box column Desired: Hidden check boxes

I would like to add a style to this column to hide all checkboxes if the value is null. This question is similar to apply a template to a column of datagrid, however I cannot manually define every column in the XAML as the number and positions of the columns in the bound datatable can change.

My datatable is defined in the view model as:

    public DataTable Data
    {
        get { return data; }
        set
        {
            data = value;
            OnPropertyChanged("Data");
        }
    }

and is set in the class constructor by calling a SQL stored procedure that returns a datatable. This stored procedure can be different depending on usage so will produce different datatables at different times.

Currently, I have this code:

          <DataGrid ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True">
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn Binding="{Binding Paid}" Header="Paid?">
                        <DataGridCheckBoxColumn.ElementStyle>
                            <Style TargetType="CheckBox">
                                <Style.Triggers>
                                    <Trigger Property="IsChecked" Value="{x:Null}">
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </DataGridCheckBoxColumn.ElementStyle>
                    </DataGridCheckBoxColumn>
                </DataGrid.Columns>
            </DataGrid>

However, adding this code has changed my datagrid columns from: Headers before change

and has simply added a new checkbox column to the start of the grid: Headers after change

The newly added column does show the desired check box effect (only checkboxes with a value shown) however the original 'Paid' column is untouched.

Could somebody please let me know how to bind my style to this one column only?

Upvotes: 1

Views: 1286

Answers (1)

toadflakz
toadflakz

Reputation: 7934

You currently have AutoGenerateColumns set to true which means that the DataGrid will first use your custom column definitions and then append it's own definitions to the DataGrid which is why you get the first "Paid?" column and then the rest of the automatically generated columns.

To get the layout that you want, you could to set AutoGenerateColumns to false and provide all the definitions of the columns.

Otherwise, try assigning a local resource to the DataGrid to style all DataGridCheckBoxColumns with your custom ElementStyle. Also note that you could simply set the IsThreeState property to false on the column as well which should stop the {x:Null} state appearing.

Update:

Looking deeper into this, there may be an issue with styling the DataGridCheckBoxColumn with AutoGenerateColumns set to true. You will need to handle the AutoGeneratingColumn event and set the ElementStyle within the handler.

Similar to:

void grid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if(e.Column is DataGridCheckBoxColumn)
    {
        var checkBoxColumn = e.Column as DataGridCheckBoxColumn;
        var resource =     Application.Current.FindResource(typeof(CheckBox));
        checkBoxColumn.ElementStyle = resource as Style;
    }
}

Source: http://www.jonathanantoine.com/2011/09/06/wpfs-datagridcheckboxcolumn-elementstyle-uses-a-wrong-default-value/

Upvotes: 1

Related Questions