2010-05-27 159 views

回答

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

問候

+0

顛覆了一個非常古老的答案。我正在嘗試這個解決方案,但是我有一個帶有AccessText的標籤,並且我得到了System.Windows.Documents.Run元素作爲OriginalSource。這不是一個visual或visual3D元素,因此GetParent會引發異常。任何想法如何去做呢? – 2015-10-09 12:25:34

15

我有這個相同的問題和f由於another StackOverflow post,我們找到了一個很好的解決方案。

在control.xaml的TreeView的元素,你可以直接掛接到TreeViewItem的Selected事件:

<TreeView ItemsSource="{StaticResource Array}" TreeViewItem.Selected="TreeViewItem_Selected"/> 

然後在你的control.xaml.cs後面的代碼,你可以從RoutedEventArgs搶選定樹型視圖和將其設置爲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; 
} 

乾淨整潔。希望能幫助別人!

+0

對於XAML代碼+1。完美解決了這個問題。 (所接受的答案(我也贊同))。 – 2012-02-16 09:18:57

+2

在我看來,這是最好的方法!只有一個缺陷:當您嘗試通過單擊摺疊圖標摺疊未選擇的項目時,它將被選中,並且事件處理程序會阻止摺疊它。在切換「IsExpanded」屬性後,你必須在'if(!e.Handled){...}'中封裝事件處理程序並設置'e.Handled = true;'。 – kroimon 2012-09-13 21:41:46

+0

此問題的另一個問題是,當您單擊已選樹視圖時,它不會摺疊或展開。 – 2016-04-21 14:10:22

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); 
} 
2

我有同樣的問題,我用Style的功能,所以你不需要處理事件。

我定義了一個樣式爲樹型視圖

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

輝煌的解決方案! – l33t 2015-07-19 21:15:52

-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); 
     } 

這裏是答案,享受它

答:阿里Rahimy

0

另一種計算策略是使用附加propperties。

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