Change the location of the TreeView to multiple ListBox

I am trying to change the location of a data tree with data binding from this:

alt text

To that:

alt text

And, of course, the choice should work correctly:

alt text

Do you have any ideas on how to do this. I tried to change the template, but I can not find a way to do this. Maybe the component already exists ...

Thank you for your help !

+3
source share
3 answers

I finally found a way out, but, as you say, Charlie, it includes creating a ListBox:

  • I am creating a new CustomControl that inherits from Control (I could not use either Selector or TreeView, because I would not be able to control the SelectedItem property from the derived class)
  • CustomControl ItemsControl. ItemControl ItemTemplate, DataTemplate, ListBox.
  • CustomControl Depth int. ListBox, .
  • CustomControl ListBoxes: ItemsSource ListBoxs SelectedItems ListBox .
  • CustomControl SelectedItem SelectionChanged (, ).
  • IsReallySelected ListBoxItem. IsSelected ViewModel IsSelected ListBoxItem. , , ListBoxItem ListBox IsSelectionActive, true.

( ) .

0

. , HierarchicalDataTemplate, ItemsControls, . , TreeView XAML, . . , , , XAML, HierarchicalDataTemplate XAML .

, 2 ( ), :

<Window.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
</Window.Resources>

<StackPanel Orientation="Horizontal">
    <ListBox Name="Level1" Width="150" Height="150"
             ItemsSource="{Binding Collection}" 
             ItemTemplate="{StaticResource ItemTemplate}"/>
    <ListBox Name="Level2" Width="150" Height="150"
             ItemsSource="{Binding ElementName=Level1, Path=SelectedValue.Children}"
             ItemTemplate="{StaticResource ItemTemplate}"/>
    <ListBox Name="Level3" Width="150" Height="150"
             ItemsSource="{Binding ElementName=Level2, Path=SelectedValue.Children}"
             ItemTemplate="{StaticResource ItemTemplate}"/>
</StackPanel>

Collection - , Children, .

, , , 2. , . , ListBox . , , ListBox .

+4

, , . TreeView : - "VisibleWhenCurrentOf".

:

  • TreeViewItem ListBox ControlTemplate ItemsPresenter.

  • TreeViewItem "VisibleWhenCurrentOf", ItemsPresenter, ListBox.

XAML :

<ControlTemplate TargetType="TreeView">
  <DockPanel>

    <ListBox
      ItemsSource="{TemplateBinding ItemsSource}"
      IsSyncrhonizedWithCurrentItem="true"
      Style="{DynamicResource BoxesTreeViewBoxStyle}"
      ItemTemplate="{Binding HeaderTemplate}"
      ItemTemplateSelector="{Binding HeaderTemplateSelector}" />

    <ItemsPresenter />
  </DockPanel>
</ControlTemplate>

<ControlTemplate TargetType="TreeViewItem">
  <DockPanel
    local:VisibilityHelper.VisibleWhenCurrentOf="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor,HeaderedItemsControl,2}">

    <ListBox
      ItemsSource="{TemplateBinding ItemsSource}"
      IsSyncrhonizedWithCurrentItem="true"
      Style="{DynamicResource BoxesTreeViewBoxStyle}"
      ItemTemplate="{Binding HeaderTemplate}"
      ItemTemplateSelector="{Binding HeaderTemplateSelector}" />

    <ItemsPresenter />
  </DockPanel>
</ControlTemplate>

, . , "+" ListBox, , , ListBox, .

BoxesTreeViewBoxStyle ListBox, . , ListBox , ControlTemplate, ListBox, .

VisibleWhenCurrentOf:

public class VisibilityHelper : DependencyObject
{

  // VisibleWhenCurrentOf
  public static object GetVisibleWhenCurrentOf(DependencyObject obj) { return (object)obj.GetValue(VisibleWhenCurrentOfProperty); }
  public static void SetVisibleWhenCurrentOf(DependencyObject obj, object value) { obj.SetValue(VisibleWhenCurrentOfProperty, value); }
  public static readonly DependencyProperty VisibleWhenCurrentOfProperty = DependencyProperty.RegisterAttached("VisibleWhenCurrentOf", typeof(object), typeof(VisibilityHelper), new UIPropertyMetadata
  {
    PropertyChangedCallback = (sender, e) =>
    {
      var element = sender as FrameworkElement;
      if(e.OldValue!=null)
      {
        var oldView = e.OldValue as ICollectionView ?? CollectionViewSource.GetDefaultView(e.OldValue);
        oldView.CurrentChanged -= UpdateVisibilityBasedOnCurrentOf;
        if(e.NewValue==null) element.DataContextChanged -= UpdateVisibilityBasedOnCurrentOf;
      }
      if(e.NewValue!=null)
      {
        var newView = e.NewValue as ICollectionView ?? CollectionViewSource.GetDefaultView(e.OldValue);
        newView.CurrentChanged += UpdateVisibilityBasedOnCurrentOf;
        if(e.OldValue==null) element.DataContextChanged += UpdateVisibilityBasedOnCurrentOf;
      }
      UpdateVisibilityBasedOnCurrentOf(sender);
    }
  });

  static void UpdateVisibilityBasedOnCurrentOf(object sender, DependencyPropertyChangedEventArgs e) { UpdateVisibilityBasedOnCurrentOf(sender); }
  static void UpdateVisibilityBasedOnCurrentOf(object sender, EventArgs e) { UpdateVisibilityBasedOnCurrentOf(sender); }
  static void UpdateVisibilityBasedOnCurrentOf(object sender)
  {
    var element = sender as FrameworkElement;

    var source = GetVisibleWhenCurrentOf(element);
    var view = source==null ? null : source as ICollectionView ?? CollectionViewSource.GetDefaultView(source);

    var visible = view==null || view.CurrentItem == element.DataContext;

    element.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
  }

}

: DataContext Current , visibilty . PropertyChangedCallback , UpdateVisibiltyBasedOnCurrentOf .

TreeView:

  • .
  • .
  • HierarchicalDataTemplate, HeaderTemplate HeaderTemplateSelector
  • ItemsSource , , - ""
  • ,
0

Source: https://habr.com/ru/post/1735195/


All Articles