简体   繁体   中英

WPF - Command and property binding not working for second DataGrid in another Tab

I have a TabControl with two tabs.
Each tab has a DataGrid .

Each DataGrid has its ItemsSource bound to a different collection (items are of the same type).
This binding works well for both grids, no problems here. Their rows show correct data.

Now, I created custom headers for the grids, and in the headers I put some buttons to make a special sorting behavior.

And although everything appears to be correct, only the first DataGrid binds the buttons correctly.

VERY WEIRD BEHAVIOR: If during debugging I simply change the second grid bindings and unchange them, they start to bind correctly!!!

So, the view model properties are working correctly, the binding will work correctly only when I change them in debug mode, but not at program start (which doesn't make much sense to me)

Here is the full code:

<TabControl Grid.Row="4" Grid.RowSpan="2">

    <TabControl.Resources>
        <!--this makes the foreground black if true and gray if false, it works well -->
        <local:EnabledToBrushConverter x:Key="EnabledToBrushConverter"/> 
        
        <!--just a style for buttons, works well -->
        <Style TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Margin" Value="5 0 0 0"/>
        </Style>
        
    </TabControl.Resources>

    
    <!-- Tab 1 with grid 1 -->
    <TabItem Header="Big Item Structure">
        <DataGrid ItemsSource="{Binding BigItemsCollection}" SelectedItem="{Binding SelectedBigItem}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="False" AutoGenerateColumns="False">
            <DataGrid.InputBindings>
                <MouseBinding Gesture="LeftDoubleCLick" Command="{Binding InspectBigItemCommand}"/>
            </DataGrid.InputBindings>

            <DataGrid.Columns>
                <DataGridTextColumn Header="Type" Binding="{Binding ItemType}" IsReadOnly="True"/>

                <DataGridTextColumn Binding="{Binding Name}" IsReadOnly="True" Width="*">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Name" VerticalAlignment="Center"/>


                            <!-- this is the button with bindings that work for grid 1 (every column ok)-->
                            <Button Command="{Binding Path=DataContext.SortBigItemsByNameCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▲" 
                                    Foreground="{Binding Path=DataContext.IsBigItemsSortByName, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>



                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

                <DataGridTextColumn Binding="{Binding PropertyOneString}" IsReadOnly="True">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Property 1" VerticalAlignment="Center"/>
                            <Button Command="{Binding Path=DataContext.SortBigItemsByPropertyOneCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▼" 
                                    Foreground="{Binding Path=DataContext.IsBigItemsSortByPropertyOne, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

                <DataGridTextColumn Binding="{Binding PropertyTwoString}" IsReadOnly="True">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Property on disk" VerticalAlignment="Center"/>
                            <Button Command="{Binding Path=DataContext.SortBigItemsByPropertyTwoCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▼" 
                                    Foreground="{Binding Path=DataContext.IsBigItemsSortByPropertyTwo, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </TabItem>
    

    <!-- Tab 2 with grid 2 -->
    <TabItem Header="All Small Items" IsSelected="{Binding IsSmallItemsViewActive, Mode=TwoWay}">
        <DataGrid ItemsSource="{Binding SmallItemsCollection}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="False" AutoGenerateColumns="False">
            <DataGrid.Columns>

                <DataGridTextColumn Binding="{Binding Name}" IsReadOnly="True" Width="*">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Small Item name" VerticalAlignment="Center"/>


                            <!-- this is the button whose bindings don't work (for all columns) -->
                            <Button Command="{Binding Path=DataContext.SortSmallItemsByNameCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▲" 
                                    Foreground="{Binding Path=DataContext.IsSmallItemsSortByName, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>



                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

                <DataGridTextColumn Binding="{Binding PropertyOneString}" IsReadOnly="True">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Logical Property" VerticalAlignment="Center"/>
                            <Button Command="{Binding Path=DataContext.SortSmallItemsByPropertyOneCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▼" 
                                    Foreground="{Binding Path=DataContext.IsSmallItemsSortByPropertyOne, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

                <DataGridTextColumn Binding="{Binding PropertyTwoString}" IsReadOnly="True">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Property on disk" VerticalAlignment="Center"/>
                            <Button Command="{Binding Path=DataContext.SortSmallItemsByPropertyTwoCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▼" 
                                    Foreground="{Binding Path=DataContext.IsSmallItemsSortByPropertyTwo, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

            </DataGrid.Columns>
        </DataGrid>
    </TabItem>
</TabControl>

For some reason the TabControl disrupts something and the second tab doesn't get to the right context when using Header .

But using a HeaderTemplate with a DataTemplate solves the problem instead:

<DataGridTextColumn Binding="{Binding Name}" IsReadOnly="True" Width="*">
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name" VerticalAlignment="Center"/>
                <Button Command="{Binding Path=DataContext.SortBigItemsByNameCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▲" 
                    Foreground="{Binding Path=DataContext.IsBigItemsSortByName, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
            </StackPanel>
        </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>

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