2010-05-27 4 views

Trả lời

5

Có lẽ không phải là giải pháp thanh lịch nhất nhưng công trình này:

static DependencyObject VisualUpwardSearch<T>(DependencyObject source) 
    { 
     while (source != null && source.GetType() != typeof(T)) 
      source = VisualTreeHelper.GetParent(source); 

     return source; 
    } 

sau đó trong TreeViewItem.Selected Handler:

 private void Treeview_Selected(object sender, RoutedEventArgs e) 
     { 
      var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem; 
      if (treeViewItem != null) treeViewItem.IsExpanded = true; 
     } 

sự kỳ diệu VisualUpwardSearch được lấy từ đây: Select TreeView Node on right click before displaying ContextMenu

Trân trọng

+0

Bumping câu trả lời rất cũ. Tôi đang cố gắng giải pháp này nhưng tôi có một nhãn với AccessText và tôi nhận được phần tử System.Windows.Documents.Run như OriginalSource. Đây không phải là một phần tử trực quan hoặc visual3d và do đó GetParent ném một ngoại lệ. Bất kỳ ý tưởng làm thế nào để đi về nó? –

15

Tôi đã gặp vấn đề tương tự và f ound một giải pháp tốt nhờ another StackOverflow post.

Trong yếu tố TreeView của control.xaml, bạn có thể treo trực tiếp vào sự kiện được lựa chọn của TreeViewItem:

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

Sau đó trong mã control.xaml.cs của bạn đằng sau, bạn có thể lấy đó chọn TreeViewItem từ RoutedEventArgs và đặt thành 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; 
} 

Đẹp và sạch sẽ. Hy vọng rằng sẽ giúp một ai đó!

+0

+1 cho mã XAML. Giải quyết vấn đề một cách hoàn hảo. (Vì vậy, các câu trả lời được chấp nhận (mà tôi cũng upvoted)). –

+2

Theo tôi, đây là phương pháp tốt nhất! Chỉ có một lỗ hổng: Khi bạn cố gắng thu gọn một mục không được chọn bằng cách nhấp vào biểu tượng thu gọn, nó sẽ được chọn và trình xử lý sự kiện ngăn chặn việc thu gọn nó. Bạn phải đóng gói trình xử lý sự kiện trong 'if (! E.Handled) {...}' và đặt 'e.Handled = true;' ngay sau khi chuyển đổi thuộc tính 'IsExpanded'. – kroimon

+0

Một vấn đề khác với điều này là khi bạn nhấp vào một cây treeview đã chọn, nó sẽ không sụp đổ hoặc mở rộng. –

0

Giải pháp được chấp nhận có hành vi lạ khi bạn đang điều hướng bằng bàn phím và không thu gọn mục khi nó đã được chọn. Ngoài ra, chỉ cần lấy được một lớp mới từ TreeViewItem và ghi đè lên phương thức MouseLeftButtonDown. Bạn cũng cần phải đặt TreeView.ItemsSource của bạn thành một tập hợp lớp TreeViewItem mới của bạn.

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

Tôi đã gặp vấn đề tương tự và tôi đã làm điều đó với chức năng Style để bạn không cần xử lý sự kiện.

tôi định nghĩa một kiểu cho 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> 

Phần quan trọng là phải xác định Checkbox trong ControlTemplate và các ràng buộc với nó. Khi CheckBox được chọn, mục sẽ được mở rộng chỉ với một cú nhấp chuột.

<CheckBox Style="{StaticResource TreeViewItemCB}" IsChecked="{Binding Path=IsExpanded,Mode=OneWayToSource,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"> 

đây là kiểu dành cho hộp kiểm để nó trải dài và không hiển thị hộp có nét.

<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

Giải pháp tuyệt vời! – l33t

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

Dưới đây là câu trả lời, Thưởng thức nó

Trả lời bởi: Ali Rahimy

0

approch khác sẽ được sử dụng propperties đính kèm.

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

Và sau đó bạn có thể sử dụng nó như thế này.

<TreeView controls:VirtualOneClickExpandButtonBehavior.Enabled="true" ItemsSource="{Binding HierarchicalModel}"/> 

Đây là sự chấp thuận tốt nếu bạn sử dụng mẫu MVVM vì bạn không cần codebehind.

Và thaks để Markust cho VisualSearchwardSearch của mình (DependencyObject source)