WPF:单击 TreeView 内的 DataGrid 行不会触发 TreeView.SelectedItemChanged
WPF: Clicking on a DataGrid Row inside a TreeView does not trigger TreeView.SelectedItemChanged
我是 WPF 的新手,并且受现有代码的困扰。
我们有一棵树,里面有很多branches/leaves。在一个分支中,我们有一个 DataGrid。
如果我们单击网格的空白区域(没有行),那么 TreeView.SelectedItemChanged 会正确调用。在我们的例子中,SelectedItem = 'SelectedGridBorder'(见下文 XAML)
但是,如果我们单击网格的 row/cell,行会获得焦点,但不会调用 TreeView.SelectedItemChanged。
所以TreeView.SelectedItem还是之前选择的项目。
有可能实现这个(根据我的)逻辑行为,所以当点击一行时,TreeView.SelectedItemChanged 应该被自动调用,TreeView.SelectedItem 应该是 'SelectedGridBorder',就像点击没有行的网格区域。
为什么 'SelectedItemChanged' 单击网格行与单击没有行的网格不同?
谢谢。
XAML:
<TreeView x:Name="CalculationDataTree" .....>
<Cinch:EventCommander.Mappings>
<Cinch:CommandEvent
Command="{Binding Path=DataContext.SelectionChangeCommand ....
Event="SelectedItemChanged"
Cinch:CommandEvent.CommandParameter="{Binding ElementName=CalculationDataTree,Path=SelectedItem}"/>
...
<TreeViewItem x:Name="Params" ...>
<TreeViewItem.Header>
<TextBlock>Parameters</TextBlock>
</TreeViewItem.Header>
<TreeViewItem x:Name="Dates" Margin="0,6,0,0">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="4,10">Date(s)</TextBlock>
<ContentControl Margin="4,6" Content="{Binding}" ContentTemplate="{StaticResource OwnEditorTemplate}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<Border Name="SelectedGridBorder" ... >
<StackPanel Orientation="Vertical">
<TextBlock Margin="4,10">Other parameters</TextBlock>
<StackPanel Orientation="Horizontal">
<DockPanel>
<dg:DataGrid Height="300" Width="600" Name="dataGrid" ....>
<dg:DataGrid.Columns>
...
</dg:DataGrid.Columns>
的答案
Why is it different for 'SelectedItemChanged' to click on a grid row, or click on a grid where no rows are?
MouseDown 是冒泡事件。发生的事情是您的 DataGrid 的 TextBox 将事件标记为已处理,因此它永远不会到达 TreeViewItem(WPF 会自动创建 TreeViewItem,即使您没有明确将其包含在您的标记中)。如果您单击 Header 或 RowSelector,它们不会将事件标记为已处理。
获得您期望的行为
//WPF creates the TreeViewItem automatically if you didn't include it
<TreeViewItem PreviewMouseDown="TreeviewItem_PreviewMouseDown">
<Border Name="SelectedGridBorder" ... >
<StackPanel Orientation="Vertical">
<TextBlock Margin="4,10">Other parameters</TextBlock>
<StackPanel Orientation="Horizontal">
处理者
private void TreeviewItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var treeViewItem = sender as TreeViewItem;
treeViewItem.IsSelected = true;
}
我是 WPF 的新手,并且受现有代码的困扰。
我们有一棵树,里面有很多branches/leaves。在一个分支中,我们有一个 DataGrid。
如果我们单击网格的空白区域(没有行),那么 TreeView.SelectedItemChanged 会正确调用。在我们的例子中,SelectedItem = 'SelectedGridBorder'(见下文 XAML)
但是,如果我们单击网格的 row/cell,行会获得焦点,但不会调用 TreeView.SelectedItemChanged。 所以TreeView.SelectedItem还是之前选择的项目。 有可能实现这个(根据我的)逻辑行为,所以当点击一行时,TreeView.SelectedItemChanged 应该被自动调用,TreeView.SelectedItem 应该是 'SelectedGridBorder',就像点击没有行的网格区域。
为什么 'SelectedItemChanged' 单击网格行与单击没有行的网格不同?
谢谢。
XAML:
<TreeView x:Name="CalculationDataTree" .....>
<Cinch:EventCommander.Mappings>
<Cinch:CommandEvent
Command="{Binding Path=DataContext.SelectionChangeCommand ....
Event="SelectedItemChanged"
Cinch:CommandEvent.CommandParameter="{Binding ElementName=CalculationDataTree,Path=SelectedItem}"/>
...
<TreeViewItem x:Name="Params" ...>
<TreeViewItem.Header>
<TextBlock>Parameters</TextBlock>
</TreeViewItem.Header>
<TreeViewItem x:Name="Dates" Margin="0,6,0,0">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="4,10">Date(s)</TextBlock>
<ContentControl Margin="4,6" Content="{Binding}" ContentTemplate="{StaticResource OwnEditorTemplate}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<Border Name="SelectedGridBorder" ... >
<StackPanel Orientation="Vertical">
<TextBlock Margin="4,10">Other parameters</TextBlock>
<StackPanel Orientation="Horizontal">
<DockPanel>
<dg:DataGrid Height="300" Width="600" Name="dataGrid" ....>
<dg:DataGrid.Columns>
...
</dg:DataGrid.Columns>
Why is it different for 'SelectedItemChanged' to click on a grid row, or click on a grid where no rows are?
MouseDown 是冒泡事件。发生的事情是您的 DataGrid 的 TextBox 将事件标记为已处理,因此它永远不会到达 TreeViewItem(WPF 会自动创建 TreeViewItem,即使您没有明确将其包含在您的标记中)。如果您单击 Header 或 RowSelector,它们不会将事件标记为已处理。
获得您期望的行为
//WPF creates the TreeViewItem automatically if you didn't include it
<TreeViewItem PreviewMouseDown="TreeviewItem_PreviewMouseDown">
<Border Name="SelectedGridBorder" ... >
<StackPanel Orientation="Vertical">
<TextBlock Margin="4,10">Other parameters</TextBlock>
<StackPanel Orientation="Horizontal">
处理者
private void TreeviewItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var treeViewItem = sender as TreeViewItem;
treeViewItem.IsSelected = true;
}