Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 898197
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T15:00:23+00:00 2026-05-15T15:00:23+00:00

Inspired by this post , I’m trying to use a TreeView inside the AutoCompleteBox’s

  • 0

Inspired by this post, I’m trying to use a TreeView inside the AutoCompleteBox’s popup in order to show hierarchical data.

Here’s what i did:

  1. I Made my own TreeView that implements ISelectionAdapter (not sure it’s perfect)

  2. Edit AutoCompleteBox template and change the selector to my treeview

  3. Try Bind my ViewModel to it

Unfortunately this is not working.
i checked my new TreeView with the same binding to the same object and it works prefectly when it’s outside of a AutoCompleteBox template.

Any idea? any special way to implement ISelectionAdapter for treeview? did i missed something?

couldn’t find any example for it on the web…

Thanks.

  • 1 1 Answer
  • 1 View
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T15:00:24+00:00Added an answer on May 15, 2026 at 3:00 pm

    I managed to write it eventually.

    Made a custom control for it. it still need to be refined, but it works good:

    Generic.xaml :

    <ControlTemplate x:Key="CommonValidationToolTipTemplate" TargetType="ToolTip">
        <Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">
            <Grid.RenderTransform>
                <TranslateTransform x:Name="Translation" X="-25"/>
            </Grid.RenderTransform>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="OpenStates">
                    <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0"/>
                        <VisualTransition GeneratedDuration="0:0:0.2" To="Open">
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="Translation">
                                    <DoubleAnimation.EasingFunction>
                                        <BackEase Amplitude=".3" EasingMode="EaseOut"/>
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                                <DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                            </Storyboard>
                        </VisualTransition>
                    </VisualStateGroup.Transitions>
                    <VisualState x:Name="Closed">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Open">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="Translation"/>
                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>
            <Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>
            <Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>
            <Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>
            <Border Background="#FFDC000C" CornerRadius="2">
                <TextBlock Foreground="White" MaxWidth="250" Margin="8,4,8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}" UseLayoutRounding="false"/>
            </Border>
        </Grid>
    </ControlTemplate>
    <Style TargetType="local:AutoCompleteTreeView"
           xmlns:System="clr-namespace:System;assembly=mscorlib">
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Padding" Value="2"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFA3AEB9" Offset="0"/>
                    <GradientStop Color="#FF8399A9" Offset="0.375"/>
                    <GradientStop Color="#FF718597" Offset="0.375"/>
                    <GradientStop Color="#FF617584" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Background" Value="#FFFFFFFF"/>
        <Setter Property="Foreground" Value="#FF000000"/>
        <Setter Property="MinWidth" Value="45"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:AutoCompleteTreeView">
                    <Grid Opacity="{TemplateBinding Opacity}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="PopupStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.1" To="PopupOpened"/>
                                    <VisualTransition GeneratedDuration="0:0:0.2" To="PopupClosed"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="PopupOpened">
                                    <Storyboard>
                                        <DoubleAnimation To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PopupBorder"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PopupClosed">
                                    <Storyboard>
                                        <DoubleAnimation To="0.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PopupBorder"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="ValidationStates">
                                <VisualState x:Name="Valid"/>
                                <VisualState x:Name="InvalidUnfocused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="InvalidFocused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <System:Boolean>True</System:Boolean>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <TextBox x:Name="Text" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" IsTabStop="True" Margin="0" Padding="{TemplateBinding Padding}" Style="{TemplateBinding TextBoxStyle}"/>
                        <Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed">
                            <ToolTipService.ToolTip>
                                <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource CommonValidationToolTipTemplate}">
                                    <ToolTip.Triggers>
                                        <EventTrigger RoutedEvent="Canvas.Loaded">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <System:Boolean>true</System:Boolean>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>
                                    </ToolTip.Triggers>
                                </ToolTip>
                            </ToolTipService.ToolTip>
                            <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
                                <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
                                <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
                            </Grid>
                        </Border>
                        <Popup x:Name="Popup">
                            <Grid Opacity="{TemplateBinding Opacity}">
                                <Border x:Name="PopupBorder" BorderThickness="0" Background="#11000000" HorizontalAlignment="Stretch" Opacity="0">
                                    <Border.RenderTransform>
                                        <TranslateTransform X="1" Y="1"/>
                                    </Border.RenderTransform>
                                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" HorizontalAlignment="Stretch" Opacity="1.0" Padding="0">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FFDDDDDD" Offset="0"/>
                                                <GradientStop Color="#AADDDDDD" Offset="1"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <Border.RenderTransform>
                                            <TransformGroup>
                                                <TranslateTransform X="-1" Y="-1"/>
                                            </TransformGroup>
                                        </Border.RenderTransform>
                                        <local:TreeViewSelectionAdapter x:Name="SelectionAdapter" BorderThickness="0" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemTemplate="{TemplateBinding ItemTemplate}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
                                    </Border>  
                                </Border>  
                            </Grid>
                        </Popup>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    AutoCompleteTreeView.cs:

    public class AutoCompleteTreeView : AutoCompleteBox
    {
        public AutoCompleteTreeView()
        {
            DefaultStyleKey = typeof(AutoCompleteTreeView);
        }
    }
    

    TreeViewSelectionAdapter.cs:

    public class TreeViewSelectionAdapter : TreeView, ISelectionAdapter
    {
        private object lastSelectedItem = null;
    
        /// <summary>
        ///This prevents the text box of the AutoCompleteBox control from being updated continuously.
        /// </summary>
        private bool IgnoreAnySelection { get; set; }
    
        /// <summary>
        /// An event that indicates that a selection is complete and has been
        /// made, effectively a commit action.
        /// </summary>
        public event RoutedEventHandler Commit;
    
        /// <summary>
        /// An event that indicates that the selection operation has been
        /// canceled.
        /// </summary>
        public event RoutedEventHandler Cancel;
    
        /// <summary>
        /// Initializes a new instance of the SelectorSelectionAdapter class.
        /// </summary>
        public TreeViewSelectionAdapter()
        {
            base.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(OnSelectionChanged);
            MouseLeftButtonUp += OnSelectorMouseLeftButtonUp;
    
        }
    
        void OnSelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
    
            if (IgnoreAnySelection)
            {
                return;
            }
    
            SelectionChangedEventHandler handler = this.SelectionChanged;
            if (handler != null)
            {
                IList oldSelectedItem = new List<object>();
                if (lastSelectedItem != null)
                    oldSelectedItem.Add(lastSelectedItem);
    
                if (SelectionChanged != null)
                    handler(this, new SelectionChangedEventArgs(oldSelectedItem, new List<object> { this.SelectedItem }));
    
                lastSelectedItem = this.SelectedItem;
    
            }
        }
    
        public new object SelectedItem
        {
            get
            {
                return base.SelectedItem;
            }
    
            set
            {
                this.SelectItem(value);
            }
        }
    
        /// <summary>
        /// Handles the mouse left button up event on the selector control.
        /// </summary>
        private void OnSelectorMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IgnoreAnySelection = false;
    
            OnSelectionChanged(this, null);
            OnCommit(this, new RoutedEventArgs());
        }
    
    
        public event SelectionChangedEventHandler SelectionChanged;
    
    
    
        /// <summary>
        /// Gets or sets the items source.
        /// </summary>
        public new IEnumerable ItemsSource
        {
            get { return base.ItemsSource; }
    
            set
            {
                if (base.ItemsSource != null)
                {
                    INotifyCollectionChanged notify = base.ItemsSource as INotifyCollectionChanged;
                    if (notify != null)
                    {
                        notify.CollectionChanged -= OnCollectionChanged;
                    }
                }
    
                base.ItemsSource = value;
    
                if (base.ItemsSource != null)
                {
                    INotifyCollectionChanged notify = base.ItemsSource as INotifyCollectionChanged;
                    if (notify != null)
                    {
                        notify.CollectionChanged += OnCollectionChanged;
                    }
                }
            }
        }
    
        /// <summary>
        /// Handles the CollectionChanged event, resetting the selection
        /// ignore flag.
        /// </summary>
        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            IgnoreAnySelection = true;
        }
    
    
        /// <summary>
        /// Process a key down event.
        /// </summary>
        public void HandleKeyDown(KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Enter:
                    IgnoreAnySelection = false;
                    OnCommit(this, e);
                    e.Handled = true;
                    break;
    
    
                case Key.Down:
                    if ((ModifierKeys.Alt & Keyboard.Modifiers) == ModifierKeys.None)
                    {
                        IgnoreAnySelection = true;
                        //SelectedIndexIncrement();
                        TreeView tv = this.FindName("SelectionAdapter") as TreeView;
    
                        tv.KeyDown += new KeyEventHandler(tv_KeyDown);
                        tv.Focus();
    
                        List<TreeViewItem> ls = new List<TreeViewItem>(tv.GetContainers());
                        ls[0].Focus();
                        e.Handled = true;
    
                    }
                    break;
    
                case Key.Escape:
                    OnCancel(this, e);
                    e.Handled = true;
                    break;
    
                default:
                    break;
            }
        }
    
        void tv_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Enter:
    
                    IgnoreAnySelection = false;
    
                    OnSelectionChanged(this, null);
                    OnCommit(this, new RoutedEventArgs());
                    break;
            }
        }
    
    
    
        /// <summary>
        /// Fires the Commit event.
        /// </summary>
        private void OnCommit(object sender, RoutedEventArgs e)
        {
            RoutedEventHandler handler = Commit;
            if (handler != null)
            {
                handler(sender, e);
            }
    
            AfterAdapterAction();
        }
    
        /// <summary>
        /// Fires the Cancel event.
        /// </summary>
        private void OnCancel(object sender, RoutedEventArgs e)
        {
            RoutedEventHandler handler = Cancel;
            if (handler != null)
            {
                handler(sender, e);
            }
    
            AfterAdapterAction();
        }
    
        /// <summary>
        /// Change the selection after the actions are complete.
        /// </summary>
        private void AfterAdapterAction()
        {
            this.SetSelectedContainer(null);
        }
    
        /// <summary>
        /// Initializes a new instance of a DataGridAutomationPeer.
        /// </summary>
        public AutomationPeer CreateAutomationPeer()
        {
            return new TreeViewAutomationPeer(this);
        }
    }
    

    Using the control:

    <ccontrols:AutoCompleteTreeView  x:Name="textbox" MinimumPrefixLength="1" IsEnabled="True" ItemsSource="{Binding MyNodes}"  >
            <ccontrols:AutoCompleteTreeView.ItemTemplate>
                <hirarch:HierarchicalDataTemplate ItemsSource="{Binding MyNodes}" >
                    <TextBlock Text="{Binding Name}" />
                </hirarch:HierarchicalDataTemplate>
            </ccontrols:AutoCompleteTreeView.ItemTemplate>
        </ccontrols:AutoCompleteTreeView>
    

    The hierarchy objects:

    public class Node
    {
        public string Name { get; set; }
        public List<Node> MyNodes { get; set; }
    
        public override string ToString()
        {
            return Name;
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I created a simple application inspired by this example in order to test all
recently this post inspired me, I want to track my own life, too. I
inspired by this answer I'm trying to map a property on a model class
This question is inspired by this post: reason for memory leakage in C C++
Inspired by this question , I was trying to find out what exactly happens
I was inspired by this post called Only fast languages are interesting to look
Inspired by this question , I'd like to know whether there is any trick
Inspired by this discussion , after some googling I wasn't able to find an
This question is inspired by this question . I'd like to get a dictionary
My question is partially inspired by this article written by Eric Lippert: http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx Using

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.