2013-08-23 39 views
7

Tôi đang cố gắng để thiết lập IsExpanded tài sản của TreeView mục của tôi bằng cách sử dụng mẫu có điều kiện, trong XAML:Thiết IsExpanded trên WPF TreeViewItem từ một DataTrigger

<DataTrigger Binding="{Binding MyStatus}" Value="Opened"> 
    <Setter TargetName="MyTextBlock" Property="Foreground" Value="Green"/> 
    <Setter Property="TreeViewItem.IsExpanded" Value="True" /> 
</DataTrigger> 

Khi tôi đặt MyStatus tài sản từ C# mã, màu sắc được thay đổi (vì vậy DataTrigger hoạt động), nhưng các nút không được mở rộng.

_myItems[0].MyStatus = MyStatus.Opened; 

Làm thế nào tôi có thể thiết lập TreeViewItem.IsExpanded tài sản từ một DataTrigger?

Khi tôi khởi động ứng dụng, màu sắc được thiết lập một cách chính xác, nhưng các nút màu xanh lá cây không được mở rộng:

Screenshot just after starting the application

Và sau khi thay đổi giá trị của _myItems[0].MyStatus_myItems[1].MyStatus, màu sắc được thay đổi cho phù hợp , nhưng nút màu xanh lá cây vẫn chưa được mở rộng.

Screenshot after clicking the Button1

Full Mã (XAML)

Mã đầy đủ là một chút dài, nhưng đó là 90% soạn sẵn.

<Window x:Class="WpfApplication6.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="150" Width="250"> 
    <DockPanel> 
     <DockPanel.Resources> 
      <HierarchicalDataTemplate ItemsSource="{Binding SubItems}" x:Key="MyTemplate"> 
       <StackPanel Orientation="Horizontal"> 
        <!-- ... --> 
        <TextBlock x:Name="MyTextBlock" Foreground="Green" Text="{Binding Name}" /> 
       </StackPanel> 

       <HierarchicalDataTemplate.Triggers> 
        <DataTrigger Binding="{Binding MyStatus}" Value="Closed"> 
         <Setter TargetName="MyTextBlock" Property="Foreground" Value="Red"/> 
         <Setter Property="TreeViewItem.IsExpanded" Value="False" /> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding MyStatus}" Value="Opened"> 
         <Setter TargetName="MyTextBlock" Property="Foreground" Value="Green"/> 
         <Setter Property="TreeViewItem.IsExpanded" Value="True" /> 
        </DataTrigger> 
       </HierarchicalDataTemplate.Triggers> 
      </HierarchicalDataTemplate> 
     </DockPanel.Resources> 

     <Button Name="button1" Click="button1_Click" DockPanel.Dock="Top" Content="Button1"/> 
     <TreeView Name="treeView1" ItemsSource="{Binding MyItems}" ItemTemplate="{StaticResource MyTemplate}"/> 
    </DockPanel> 
</Window> 

Full Mã (C#)

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 

namespace WpfApplication6 
{ 
    public partial class MainWindow : Window 
    { 
     private ObservableCollection<MyItemCollection> _myItems; 

     public MainWindow() { 
      InitializeComponent(); 

      _myItems = new ObservableCollection<MyItemCollection> { 
       new MyItemCollection { Name = "Parent1", MyStatus = MyStatus.Closed, SubItems = { new MyItemCollection { Name = "Child1" } } }, 
       new MyItemCollection { Name = "Parent2", MyStatus = MyStatus.Opened, SubItems = { new MyItemCollection { Name = "Child2" } } } 
      }; 

      DataContext = new { 
       MyItems = _myItems 
      }; 
     } 

     private void button1_Click(object sender, RoutedEventArgs e) { 
      _myItems[0].MyStatus = MyStatus.Opened; 
      _myItems[1].MyStatus = MyStatus.Closed; 
     } 
    } 

    public enum MyStatus 
    { 
     Closed, 
     Opened 
    } 

    public class MyItemCollection : INotifyPropertyChanged 
    { 
     public MyItemCollection() { 
      SubItems = new ObservableCollection<MyItemCollection>(); 
      _myStatus = MyStatus.Closed; 
     } 

     public string Name { get; set; } 

     public ObservableCollection<MyItemCollection> SubItems { get; set; } 

     private MyStatus _myStatus; 
     public MyStatus MyStatus { 
      get { return _myStatus; } 
      set { _myStatus = value; NotifyPropertyChanged("MyStatus"); } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void NotifyPropertyChanged(String propertyName) { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 
+0

Liên quan: [WPF DataBound treeview mở rộng/thu gọn] (http://stackoverflow.com/q/1717654/324969), nhưng chúng sử dụng 'Style' trong khi tôi sử dụng' DataTrigger'. –

Trả lời

9

Có một vài điều sai trái ở đây. Đầu tiên là bạn đang thiết lập thuộc tính TreeViewItem.IsSelected trên HierarchicalDataTemplate. Điều này sẽ không hoạt động. Thay vào đó, bạn sẽ cần phải thiết lập một ItemContainerStyle trên TreeView:

<TreeView> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="{x:Type TreeViewItem}"> 
     <!-- put logic for handling expansion here --> 
     </Style> 
    </TreeView.ItemContainerStyle> 
</TreeView> 

Bạn không thể chỉ đặt Trigger ở đây, tuy nhiên. Bởi vì DependencyProperty value precedence, nếu người dùng của bạn nhấp vào các nút để mở rộng hoặc thu gọn chúng, trình kích hoạt của bạn sẽ không nằm trong danh sách ưu tiên (đó là giá trị cục bộ). Do đó, đặt cược tốt nhất của bạn là tạo một IValueConverter mới để chuyển đổi từ MyStatus thành bool. Và sau đó thiết lập một TwoWay ràng buộc trong một Setter trong Style:

<Style TargetType="{x:Type TreeViewItem}"> 
    <Setter Property="IsExpanded" 
      Value="{Binding MyStatus, Converter={StaticResource statusToBool}}" /> 
</Style> 

và chuyển đổi của bạn:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    return ((MyStatus)value) == MyStatus.Opened; 
} 

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    return ((bool)value) ? MyStatus.Opened : MyStatus.Closed; 
} 
+0

Cảm ơn, tôi đã sử dụng trực tiếp thuộc tính boolean 'MyExpanded' ngoài trường' MyStatus' enum, để tránh trình biến đổi ('ConversionBack' sẽ có vấn đề vì có nhiều hơn hai giá trị trong enum). –

1

tôi phải làm một cái gì đó tương tự, và tôi giải quyết nó theo cách này:

<TreeView ItemsSource="{Binding source}" 
      SnapsToDevicePixels="{Binding Path=myStatusToBool}" 
      > 
    <TreeView.ItemContainerStyle> 
    <Style> 
     <Setter Property="TreeViewItem.IsExpanded" 
       Value="False" 
       /> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=SnapsToDevicePixels,RelativeSource={RelativeSource AncestorType=TreeView}}" 
        Value="True"> 
      <Setter Property="TreeViewItem.IsExpanded" 
        Value="True" 
        /> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    </TreeView.ItemContainerStyle> 

    <TreeView.Resources> 
    ..... 
    ..... 
    </TreeView.Resources> 
</TreeView> 
+0

Perdón por algún motivo se Borro la mồi parte: –

+0

+3

Stack Overflow không phải là một trang web đa ngôn ngữ. Xin vui lòng viết bằng tiếng Anh. –