2017-08-29 13 views
-1

我正在使用自定义对象TreeView延迟加载TreeViewItem自定义加载方法取决于它们的嵌套类型

目标:在TreeViewItem.Expanded事件我想打电话给A.B.LoadChilds()取决于嵌套式的实现延迟加载。

型号

public class A 
{ 
    public A() 
    { 
     Childs = new ObservableCollection<B>(); 
    } 
    public string Name {get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) //Type is unimportant 
    { 
     // adding childs 
    } 
} 

public class B 
{ 
    public B() 
    { 
     Childs = new ObservableCollection<B>(); //Yes, rekursiv 
    } 
    public string Name {get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) 
    { 
     // adding childs 
    } 
} 

MainWindow.xaml

<TreeView x:Name="Tree"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type model:A}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type model:B}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 

代码隐藏

//Init 
List<A> ListOfAs = getAs(dbConnection); 
Tree.ItemsSource = ListOfAs; 

问题:达成目标的最佳方式是什么?

+0

我q uestion简单地设置为“搁置”并不能帮助我。只是说什么不清楚。特别是其他人理解这个问题,并且已经给出了解决方案。 – Syrlia

回答

1

肯定是有“漂亮”的方式 - 无在代码隐藏的事件处理程序中编写业务逻辑。

介绍的图模型类布尔IsExpanded,结合TreeViewItem.IsExpanded到该属性,并触发在设定器LoadChilds方法:

<TreeView x:Name="Tree"> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="TreeViewItem"> 
      <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}"/> 
     </Style> 
    </TreeView.ItemContainerStyle> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type model:A}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type model:B}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 
public class A 
{ 
    public A() 
    { 
     // null is a placeholder. 
     // without any items TreeViewItem will not even show expander 
     // (Expand event won't work either) 
     Childs = new ObservableCollection<B>() { null }; 
    } 

    public string Name { get; set; } 

    private bool _isExpanded; 
    public bool IsExpanded 
    { 
     get 
     { 
      return _isExpanded; 
     } 
     set 
     { 
      _isExpanded = value; 
      // when node is expanded, RELOAD! 
      if (_isExpanded) 
       LoadChilds(); 
     } 
    } 

    public ObservableCollection<B> Childs { get; set; } 

    public void LoadChilds() 
    { 
     Childs.Clear(); 
     Childs.Add(new B() { Name = Guid.NewGuid().ToString() }); 
    } 
} 

B是在本试验例中几乎相同,但我想LoadChilds逻辑将在不同的真实应用程序

public class B 
{ 
    public B() 
    { 
     Childs = new ObservableCollection<B>() { null }; 
    } 

    public string Name { get; set; } 

    private bool _isExpanded; 
    public bool IsExpanded 
    { 
     get 
     { 
      return _isExpanded; 
     } 
     set 
     { 
      _isExpanded = value; 
      if (_isExpanded) 
       LoadChilds(); 
     } 
    } 

    public ObservableCollection<B> Childs { get; set; } 

    public void LoadChilds() 
    { 
     Childs.Clear(); 
     Childs.Add(new B() { Name = Guid.NewGuid().ToString() }); 
    } 
} 
1

您可以定义两个AB实现的接口和流延展开TreeViewItemDataContext这种类型:

public interface ICommon 
{ 
    string Name { get; set; } 
    void LoadChilds(DBConnection connection); 
} 

public class A : ICommon 
{ 
    public class A() 
    { 
     Childs = new ObservableCollection<B>(); 
    } 
    public string Name { get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) //Type is unimportant 
    { 
     // adding childs 
    } 
} 

public class B : ICommon 
{ 
    public class B() 
    { 
     Childs = new ObservableCollection<B>(); //Yes, rekursiv 
    } 
    public string Name { get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) 
    { 
     // adding childs 
    } 
} 

private void TreeView_Expanded(object sender, RoutedEventArgs e) 
{ 
    TreeViewItem tvi = e.OriginalSource as TreeViewItem; 
    ICommon obj = tvi.DataContext as ICommon; 
    if (obj != null) 
     obj.LoadChilds(...); 

} 
+0

目前我这样做。有没有更漂亮的方式?我想避免尽可能多的依赖。接口是一个依赖项。 – Syrlia

+1

“一个接口是一个依赖”应该是一个接口是一个抽象。不,没有“漂亮”的方式。如果你没有实现一个接口,你将不得不尝试将DataContext转换为A *和* a * B *以及C和任何其他可能涉及的具体类型。 – mm8