DataGridRow.IsSelected已设置,我不知道为什么

时间:2015-01-16 06:27:03

标签: c# wpf datagrid

您好,这是我的问题:

我在DataGridRow和DataGridCell的资源中定义了两种样式:

 <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="DataGridRow.IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger Property="DataGridCell.IsSelected" Value="True">
                <Setter Property="Background" Value="LightSteelBlue" />
            </Trigger>
        </Style.Triggers>
    </Style>

我基本上希望在用户选择时将一行突出显示为蓝色。

我有一个MessageWrapper和一个SignalWrapper课程。每个MessageWrapper都有一个SignalWrappers列表(有时可能为空)。因此,第一个DataGrid将显示所有MessageWrappers

<DataGrid x:Name="messageGrid"
                          Grid.Column="0"
                          Margin="3"
                          AutoGenerateColumns="False"
                          CanUserAddRows="False"
                          HorizontalScrollBarVisibility="Hidden"
                          IsReadOnly="True"
                          ItemsSource="{Binding SelectedBusWrapper.MessageWrappers}"
                          SelectedItem="{Binding SelectedBusWrapper.SelectedMessageWrapper}"
                          attachedProperties:SelectingItemAttachedProperty.SelectingItem="{Binding SelectedBusWrapper.MessageWrapperToScrollIntoView,
                                                                                                   UpdateSourceTrigger=PropertyChanged,
                                                                                                   Mode=TwoWay}">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn Width="Auto" Header="Filter">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox MaxWidth="15"
                                              MaxHeight="15"
                                              CommandParameter="{Binding}"
                                              IsChecked="{Binding Filter}"
                                              Style="{StaticResource CheckBoxStyle}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Width="9*"
                                            Binding="{Binding Message.Name}"
                                            Header="Name" />
                        <DataGridTextColumn Width="9*"
                                            Binding="{Binding HexId}"
                                            Header="Id" />
                        <DataGridTextColumn Width="11*"
                                            Binding="{Binding Message.Sender}"
                                            Header="Sender" />
                    </DataGrid.Columns>
                </DataGrid>

DataGrid的每一行都有一个CheckBox列。如果未选中CheckBox,则会在第二个SignalWrappers中显示所有DataGrid。如果选中了一个或多个,则只应显示checkec SignalWrappers的{​​{1}}。这里是MessageWrappers

DataGrid

现在,如果用户在第一个<DataGrid Grid.Column="1" Margin="3" AutoGenerateColumns="False" CanUserAddRows="False" HorizontalScrollBarVisibility="Hidden" IsReadOnly="True" ItemsSource="{Binding SelectedBusWrapper.SelectedSignalWrappers}" SelectedItem="{Binding SelectedBusWrapper.SelectedSignalWrapper}" SelectionMode="Extended"> <DataGrid.Resources> <Style TargetType="DataGridRow"> <Setter Property="IsSelected" Value="{Binding IsSelected}" /> </Style> </DataGrid.Resources> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding MouseDoubleClickCommand}" CommandParameter="{Binding}" /> </i:EventTrigger> </i:Interaction.Triggers> <DataGrid.Columns> <DataGridTemplateColumn Width="Auto" Header="Filter"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox MaxWidth="15" MaxHeight="15" CommandParameter="{Binding}" IsChecked="{Binding Filter}" Style="{StaticResource CheckBoxStyle}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Width="6*" Binding="{Binding Signal.Name}" Header="Name" /> <DataGridTemplateColumn Width="Auto" Header="Value"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox MinWidth="75" IsEditable="True" ItemsSource="{Binding Signal.Values.Values}" SelectedItem="{Binding SelectedValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> 中选择一个或多个消息,则应在第二个消息中突出显示这些消息的信号。如果用户在第二个中选择一个信号,则应在第一个DataGrid中突出显示父消息。

DataGrid类的绑定属性:

MessageWrapper

public bool IsSelected { get { return isSelected; } set { if (isSelected == value) { return; } isSelected = value; foreach (var item in SignalWrappers) { item.IsSelected = value; } RaisePropertyChanged("IsSelected"); } } 类的绑定属性:

SignalWrapper

现在我有一个奇怪的行为我无法理解:

当我检查第一个public bool IsSelected { get { return isSelected; } set { if (isSelected == value) { return; } isSelected = value; ParentMessageWrapper.IsSelected = value; RaisePropertyChanged("IsSelected"); } } 中的第一个CheckBox时:

消息突出显示,第二个DataGrid仅显示该消息的信号并突出显示它们。到目前为止这是正确的。 如果我现在检查第二条消息,它会突出显示行和这些行的所有信号。调试时我注意到发生的事情是第一个DataGrid MessageWrappers标志设置为false,并且其所有信号标志都设置为false,这是正确的。之后,第二个IsSelected标志设置为true,其所有信号标志都设置为true,这也是正确的。 然后由于某种原因我无法理解第一个MessageWrappers MessageWrapper标志的信号被设置为true,这会将IsSelected标志设置为true,这会将其他信号标志设置为真。

注意:如果我检查第三个MessageWrappers,一切都按预期工作了。

有人能理解为什么会这样吗?感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

IsSelected中设置SingleWrapper时有很多循环,因为它设置了ParentMessageWrapper.IsSelected = value;,它将返回到IsSelected中设置SingleWrapper,依此类推。

我想在SingleWrapper中制作方法就像这样:

public SetIsSelected(bool value)
{
    if (isSelected == value) {
        return;
    }
    isSelected = value;
    RaisePropertyChanged("IsSelected");
}

并将item.IsSelected = value;中的MessageWrapper更改为item.SetIsSelected(value)