简体   繁体   中英

Binding a checkbox in a datagrid header

I have a datagrid where the first column contains a checkbox to let the user selects specific rows. I have added a checkbox in the datagrid column header to check or uncheck all the rows.

Is it possible to add this functionality only with binding in XAML (no checked event).

<sdk:DataGrid AutoGenerateColumns="False" Grid.Row="1"  Name="grid" ItemsSource="{Binding myCollection, Mode=TwoWay}" >
        <sdk:DataGrid.Columns>
            <sdk:DataGridCheckBoxColumn Binding="{Binding myCollection.UserSelected, Mode=TwoWay}" >
                <sdk:DataGridCheckBoxColumn.HeaderStyle>
                    <Style TargetType="sdk:DataGridColumnHeader">
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <CheckBox x:Name="checkAll" IsThreeState="True"  
                                              IsChecked="{Binding myCollection.UserSelected, Mode=TwoWay, Converter={StaticResource threeStateConverter}}"/>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </sdk:DataGridCheckBoxColumn.HeaderStyle>
            </sdk:DataGridCheckBoxColumn>
            <sdk:DataGridTextColumn Binding="{Binding Description}" Header="Chemin" />
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>

I think there's something wrong with the "myCollection.UserSelected" part. ThreeStateConverter is a value converter that would return null when some items are selected, true when they are all selected, etc. but the Convert method is never called (even though the PropertyChanged event is raised when UserSelected is changed).

Any idea on how I can do it? Thank you.

Probably, you've solved the problem already, but nevertheless:

<navigation:Page.Resources>
    <model:MyModel x:Key="Model"/>
</navigation:Page.Resources>
...    
<data:DataGridTemplateColumn Width="Auto" >
    <data:DataGridTemplateColumn.HeaderStyle>
        <Style TargetType="datap:DataGridColumnHeader">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <CheckBox IsThreeState="True" Margin="2,0,-13,0" DataContext="{StaticResource Model}" IsChecked="{Binding Path=AllChecked, Mode=TwoWay}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </data:DataGridTemplateColumn.HeaderStyle>
    <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>

MyModel class contains bool? property that implements logic of selection. It is also used as a `DataContext of page.

I must admit that this potentially has problems if we need to change model.

EDIT: I found another way:

<navigation:Page.DataContext>
    <model:MyModel />
</navigation:Page.DataContext>
...    
<data:DataGridTemplateColumn Width="Auto" >
    <data:DataGridTemplateColumn.HeaderStyle>
        <Style TargetType="datap:DataGridColumnHeader">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <CheckBox IsThreeState="True" Margin="2,0,-13,0" IsChecked="{Binding Path=DataContext.AllChecked, ElementName=LayoutRoot, Mode=TwoWay}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </data:DataGridTemplateColumn.HeaderStyle>
    <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>

Here we bind to DataContext of root layout element (usually called LayoutRoot ) which inherits its data context from page by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM