简体   繁体   English

WPF - 命令和属性绑定不适用于另一个选项卡中的第二个 DataGrid

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

I have a TabControl with two tabs.我有一个带有两个选项卡的TabControl
Each tab has a DataGrid .每个选项卡都有一个DataGrid

Each DataGrid has its ItemsSource bound to a different collection (items are of the same type).每个DataGrid都将其ItemsSource绑定到不同的集合(项目属于同一类型)。
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.尽管一切看起来都是正确的,但只有第一个DataGrid正确绑定了按钮。

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)因此,视图 model 属性工作正常,只有当我在调试模式下更改它们时绑定才会正常工作,但在程序启动时不会(这对我来说没有多大意义)

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 .由于某种原因, TabControl中断了一些事情,并且第二个选项卡在使用Header时没有到达正确的上下文。

But using a HeaderTemplate with a DataTemplate solves the problem instead:但是将HeaderTemplateDataTemplate一起使用可以解决问题:

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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