现在您必须双击或单击+图标。如果用户点击它展开的节点上的任何地方,有没有办法实现它?
答案 0 :(得分:16)
由于another StackOverflow post,我遇到了同样的问题并找到了一个很好的解决方案。
在control.xaml的TreeView元素中,您可以直接挂钩到TreeViewItem的Selected事件:
<TreeView ItemsSource="{StaticResource Array}" TreeViewItem.Selected="TreeViewItem_Selected"/>
然后在您的control.xaml.cs代码中,您可以从RoutedEventArgs中获取所选的TreeViewItem并将其设置为IsExpanded:
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem tvi = e.OriginalSource as TreeViewItem;
if (tvi == null || e.Handled) return;
tvi.IsExpanded = !tvi.IsExpanded;
e.Handled = true;
}
干净整洁。希望这有助于某人!
答案 1 :(得分:5)
也许不是最优雅的解决方案,但这有效:
static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(T))
source = VisualTreeHelper.GetParent(source);
return source;
}
然后在TreeViewItem.Selected处理程序中:
private void Treeview_Selected(object sender, RoutedEventArgs e)
{
var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
if (treeViewItem != null) treeViewItem.IsExpanded = true;
}
VisualUpwardSearch魔术从这里获取:Select TreeView Node on right click before displaying ContextMenu
此致
答案 2 :(得分:2)
我遇到了同样的问题,我使用了Style函数,因此您无需处理该事件。
我为TreeViewItem定义了一个样式
<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
<!--<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<CheckBox Style="{StaticResource TreeViewItemCB}" IsChecked="{Binding Path=IsExpanded,Mode=OneWayToSource,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press">
<Grid Background="{StaticResource TreeViewItemBackground}" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Name="Bd">
<ContentPresenter x:Name="PART_Header" ContentSource="Header"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.Row="1"/>
</Grid>
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
重要的部分是在ControlTemplate中定义checkBox并与之绑定。选中CheckBox后,只需单击一下即可展开该项目。
<CheckBox Style="{StaticResource TreeViewItemCB}" IsChecked="{Binding Path=IsExpanded,Mode=OneWayToSource,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press">
这是checkBox的样式,因此它会拉伸并且不会显示带有笔划的框。
<Style x:Key="TreeViewItemCB" TargetType="CheckBox" BasedOn="{StaticResource baseStyle}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<ContentPresenter VerticalAlignment="Stretch" HorizontalAlignment="Stretch" RecognizesAccessKey="True"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 3 :(得分:1)
@BJennings提供了一个很好的答案。但是,如果要展开或折叠已选择的项目,则无法使用。为了改善这一点,您可以简单地添加:tvi.IsSelected = false; (如果您不在乎该项目是否处于选中状态。)
因此,整个代码如下:
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem tvi = e.OriginalSource as TreeViewItem;
if (tvi == null || e.Handled) return;
tvi.IsExpanded = !tvi.IsExpanded;
tvi.IsSelected = false;
e.Handled = true;
}
答案 4 :(得分:0)
当您使用键盘导航时,已接受的解决方案具有奇怪的行为,并且在已经选择项目时不会折叠该项目。或者,只需从TreeViewItem派生一个新类并覆盖MouseLeftButtonDown方法。您还需要将TreeView.ItemsSource设置为新TreeViewItem类的集合。
protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
if (!e.Handled && base.IsEnabled)
{
this.IsExpanded = !this.IsExpanded;
e.Handled = true;
}
base.OnMouseLeftButtonDown(e);
}
答案 5 :(得分:0)
另一个方法是使用附加属性。
public class VirtualOneClickExpandButtonBehavior : DependencyObject
{
public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(EnabledProperty);
}
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
}
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(VirtualOneClickExpandButtonBehavior),
new UIPropertyMetadata(false, EnabledPropertyChangedCallback
));
private static void EnabledPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var treeView = dependencyObject as TreeView;
if (treeView == null) return;
treeView.MouseUp += TreeView_MouseUp;
}
private static void TreeView_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
if (treeViewItem != null) treeViewItem.IsExpanded = !treeViewItem.IsExpanded;
}
static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(T))
source = VisualTreeHelper.GetParent(source);
return source;
}
}
然后你可以像这样使用它。
<TreeView controls:VirtualOneClickExpandButtonBehavior.Enabled="true" ItemsSource="{Binding HierarchicalModel}"/>
如果您使用MVVM模式,这是一个很好的方法,因为您不需要代码隐藏。
向Markust寻求他的VisualUpwardSearch(DependencyObject源代码)
答案 6 :(得分:-1)
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Cursor" Value="Hand" />
<EventSetter Event="MouseUp" Handler="TreeViewItem_Click"/>
</Style>
</TreeView.ItemContainerStyle>
private void TreeViewItem_Click(object sender, MouseButtonEventArgs e)
{
((TreeViewItem) sender).IsExpanded = !((TreeViewItem) sender).IsExpanded;
Thread.Sleep(700);
}
以下是答案,享受
回答:Ali Rahimy