我通过编写一个小工具来自学 WPF、LINQ 和 MVVM,以解析 CME XML 配置文件,如当前的生产配置。我在显示通道的 DataGrid 中添加了一个带有复选框的 DataGridTemplateColumn,以便我可以选择一些我感兴趣的通道并过滤掉其余的通道。问题是当我单击复选框时,会显示 RowDetails。
如果单击任何其他列,如何防止单击触发 RowDetails 的显示,同时仍然具有“VisibleWhenSelected”行为?我需要自己处理 RowDetails 的可见性还是有更简单的方法?
以下是添加了 ToggleButton 的更新代码,如下所示,以防万一它对其他人有用:
<DataGrid x:Name="ChannelListGrid"
DockPanel.Dock="Top"
IsReadOnly="True"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=ConfigFileXML.Root.Elements[channel]}"
RowDetailsTemplate="{StaticResource ResourceKey=ConnectionInfoTemplate}"
IsTextSearchEnabled="True"
HorizontalAlignment="Left"
AreRowDetailsFrozen="True"
RowDetailsVisibilityMode="Collapsed">
<DataGrid.Columns>
<DataGridTemplateColumn Width="Auto"
CanUserResize="False"
CanUserSort="false"
CanUserReorder="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Click="ToggleRowDetails"
Style="{StaticResource ToggleExpandButtonStyle}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Selected"
Width="Auto"
CanUserReorder="False"
CanUserResize="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Unchecked="ChannelDeselected"
Checked="ChannelSelected" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="ID"
Binding="{Binding Path=Attribute[id].Value}" />
<DataGridTextColumn Header="Name"
Binding="{Binding Path=Attribute[label].Value}" />
<DataGridTextColumn Header="Symbol Count"
Binding="{Binding Path=Descendants[product].Count}" />
</DataGrid.Columns>
</DataGrid>
这里是模板
<DataTemplate x:Key="ConnectionInfoTemplate">
<DataGrid x:Name="ConnectionListGrid"
IsReadOnly="True"
HorizontalAlignment="Left"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=Descendants[connection]}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID"
Binding="{Binding Path=Attribute[id].Value}" />
<DataGridTextColumn Header="Type"
Binding="{Binding Path=Element[type].Value}" />
<DataGridTextColumn Header="Protocol"
Binding="{Binding Path=Element[protocol].Value}" />
<DataGridTextColumn Header="Source IP"
Binding="{Binding Path=Element[ip].Value}" />
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
<SolidColorBrush x:Key="GlyphBrush"
Color="#444" />
<Style x:Key="ToggleExpandButtonStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="IsChecked"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid Width="15"
Height="13"
Background="Transparent">
<Path x:Name="ExpandPath"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="1,1,1,1"
Fill="{StaticResource GlyphBrush}"
Data="M 4 0 L 8 4 L 4 8 Z" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="Data"
TargetName="ExpandPath"
Value="M 0 4 L 8 4 L 4 8 Z" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是C#中的代码
private T FindAncestor<T>(DependencyObject depObject)
where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(depObject);
if (parent == null) return null;
var parentT = parent as T;
return parentT ?? FindAncestor<T>(parent);
}
private void ToggleRowDetails(object sender, System.Windows.RoutedEventArgs e)
{
var senderButton = sender as ToggleButton;
DataGridRow toggledRow = FindAncestor<DataGridRow>(senderButton);
if (toggledRow != null)
{
// If IsChecked is null, use false. If true, make details visible, otherwise collapse the details
toggledRow.DetailsVisibility = ( senderButton.IsChecked ?? false) ? Visibility.Visible : Visibility.Collapsed;
}
}