This is a migrated thread and some comments may be shown as answers.

RadTreeViewItem Visibility

22 Answers 939 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Kennet
Top achievements
Rank 2
Kennet asked on 22 Dec 2009, 11:16 AM
Hello!

if I set an RadTreeViewItem to  ".Visibility = Visibility.Collapsed" or ".Visibility = Visibility.Hidden", the item is not visible BUT it stil takes space in the triewview (as a empty row).

Is this a bug, or how do I make an item invisible by code?

22 Answers, 1 is accepted

Sort by
0
Miroslav
Telerik team
answered on 22 Dec 2009, 01:12 PM
Hi Kennet,

Yes, this is a known change in the TreeView for the Q3 release.

TreeView's virtualizing panel does not take these properties into account and "reserves" space for the collapsed items.

If you are not planning to use virtualization, you can change the ItemsPanel of the TreeView and its items to a StackPanel.

Are you trying to achieve some kind of filtering? In this case I can suggest removing and adding items instead of collapsing them because features like selection, check boxes and tree lines may not work correctly with collapsed items.

Sincerely yours,
Miroslav
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Aurore
Top achievements
Rank 1
answered on 03 Jan 2011, 04:29 PM
Hello,

Is there a new way to set RadTreeViewItem to  ".Visibility = Visibility.Collapsed"  ?

I tried using Stackpanel but scrolling is no more usable !
(selection, drag/drop still working... )

Thanks in advance
Aurore
0
Hristo
Telerik team
answered on 03 Jan 2011, 04:57 PM
Hello Kennet,

It's strange that you can not use the scroll viewer when switching the items panel. Can you please take a look at the attached project and check if it works for you. I'm using 2010 Q3 dlls.

Hope this will help. However if your issue continues to exist please let me know.

Regards,
Hristo
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Aurore
Top achievements
Rank 1
answered on 03 Jan 2011, 05:06 PM
I tried your sample, it contains the same feedback.

Set '50' items for your j :
for (int j = 0; j < 50; j++)

and try :

Open level 0, and try with scroll to obtain 0.30...
It is impossible, the scroll works this "gap". I think that first, it present the 0-level stackpanel scrollbar, but when we go down, the scroll size change....

Regards,
Aurore
0
Tina Stancheva
Telerik team
answered on 04 Jan 2011, 05:21 PM
Hi Kennet,

Thank you for the clarification. We reproduced the issue and we logged it in our PITS, where you can track its progress. You can also vote for the TreeViewItems Visibility issue here thus increasing its priority.

Please accept our apology for the caused inconvenience.

Best wishes,
Tina Stancheva
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Tom
Top achievements
Rank 1
answered on 11 Jan 2011, 11:55 AM
We'd like this fixed as soon as possible as well. Currently we are unable to use the RadTreeView for this reason. When is  the Q4 2010 release due?
0
Rob Peters
Top achievements
Rank 1
answered on 11 Jan 2011, 07:20 PM
We'll vote for a fix in Q4-2010 (Q1-2011) too.
Removing/Adding items (or clearing the ObservableCollection) seems the only way at the moment.

Rob
0
Petar Mladenov
Telerik team
answered on 12 Jan 2011, 01:56 PM
Hi Kennet,

The Q1 2011 beta is scheduled for 16. February 2011 and the Q1 2011 is scheduled for the middle of  March. But due to more important developing tasks, we cannot promise when this issue is going to be resolved. Still, voting is the way to increase the priority of this item. Please accept our apologies for the inconvenience caused.

Regards,
Petar Mladenov
the Telerik team
Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
0
Aurore
Top achievements
Rank 1
answered on 05 Jul 2011, 03:19 PM
Hello,

Is this problem soon corrected ?

Aurore
0
Petar Mladenov
Telerik team
answered on 08 Jul 2011, 12:25 PM
Hello Aurore,

No this issue is still not resolved as you can see in our PITS. We will be working on RadTreeView`s issues during the Q3 2011 (mid July - mid-November).

Regards,
Petar Mladenov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Brent
Top achievements
Rank 2
answered on 10 Feb 2013, 10:50 PM
Hello, this also affecting my port of a wpf project to silverlight that is not working as it should.  Can you provide an update on getting this fixed?
0
Petar Mladenov
Telerik team
answered on 13 Feb 2013, 07:19 AM
Hi Brent,

 We cannot provide an estimated time frame when this will be resolved. You can consider one of the workarounds - changing the TreeViewItemsTemplate to work with normal StackPanel but this way you will lose the Virtualization feature. However, this can be suitable in not very large trees.

Regards,
Petar Mladenov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Gonzalo
Top achievements
Rank 1
answered on 18 May 2013, 09:22 PM
Do you have the code of that workaround ("changing the TreeViewItemsTemplate to work with normal StackPanel
")?
0
Petar Mladenov
Telerik team
answered on 22 May 2013, 06:26 AM
Hello Gonzalo,

 Here is a sample code:

<Grid.Resources>
           <Style TargetType="telerik:RadTreeViewItem">
               <Setter Property="ItemsPanel">
                   <Setter.Value>
                       <ItemsPanelTemplate>
                           <StackPanel />
                       </ItemsPanelTemplate>
                   </Setter.Value>
               </Setter>
           </Style>
       </Grid.Resources>
       <telerik:RadTreeView IsEditable="True">
           <telerik:RadTreeView.ItemsPanel>
               <ItemsPanelTemplate>
                   <StackPanel />
               </ItemsPanelTemplate>
           </telerik:RadTreeView.ItemsPanel>
           <telerik:RadTreeViewItem Header="Item A" />
           <telerik:RadTreeViewItem Header="Item B" />
           <telerik:RadTreeViewItem Header="Item C" Visibility="Collapsed"/>
           <telerik:RadTreeViewItem Header="Item D" >
               <telerik:RadTreeViewItem Header="Item D1" />
               <telerik:RadTreeViewItem Header="Item D2" Visibility="Collapsed"/>
               <telerik:RadTreeViewItem Header="Item D3" />
           </telerik:RadTreeViewItem>
           <telerik:RadTreeViewItem Header="Item E" />
           <telerik:RadTreeViewItem Header="Item F" />
       </telerik:RadTreeView>
The Style applies to RadTreeViewItems and the TreeView.ItemsPanel property takes care for root level of the tree.
Please note that this setting breaks the virtualization feature of RadTreeView. But for small xaml-defined RadTreeViews  where you don't usually need virtualization, this works fine.

Regards,
Petar Mladenov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Carlos
Top achievements
Rank 1
answered on 22 May 2013, 08:01 AM
It didnt work. We control almost everything from code.

Here is XAML
<UserControl x:Class="Test.widgets.dialogs.FiltersTreeViewUC"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:local="clr-namespace:SchneiderElectricDSP.model.binding">
 
    <UserControl.Resources>
        <local:FilterHierarchyConverter x:Key="FilterHierarchyConverter" />
        <local:CheckStateConverter x:Key="CheckStateConverter"/>
 
        <telerik:ContainerBindingCollection x:Name="BindingsCollection">
            <telerik:ContainerBinding PropertyName="CheckState" Binding="{Binding Checked, Converter={StaticResource CheckStateConverter} , Mode=TwoWay}"/>
        </telerik:ContainerBindingCollection>
         
        <telerik:HierarchicalDataTemplate x:Key="ItemTemplate"
                                          ItemsSource="{Binding Converter={StaticResource FilterHierarchyConverter}}"
                                          >
            <TextBlock Text="{Binding Text}" Visibility="{Binding IsVisible}"/>
        </telerik:HierarchicalDataTemplate>
 
    </UserControl.Resources>
     
    <Grid>
        <Grid.Resources>
            <Style TargetType="telerik:RadTreeViewItem">
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <StackPanel />
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="300*" />
            <RowDefinition Height="40" />
        </Grid.RowDefinitions>
 
        <StackPanel Orientation="Horizontal" Grid.Row="0">
            <telerik:RadComboBox Name="cmbGroups"
                             IsTextSearchEnabled="True" IsEditable="False"
                             TextSearchMode="StartsWith"                            
                             Margin="3"
                             Height="27"
                             VerticalAlignment="Top"
                             HorizontalAlignment="Left"
                             Width="135" SelectionChanged="cmbGroups_SelectionChanged">
            </telerik:RadComboBox>
            <telerik:Label Name="noneLabel" Margin="3" Cursor="Hand"
                       Content="{Binding Path=CommonTranslations.txtNone, Source={StaticResource TranslationsManager}}" MouseLeftButtonUp="NoneLabel_OnMouseLeftButtonUp" />
            <telerik:RadWatermarkTextBox
                x:Name="nameFilterTextBox"
                VerticalAlignment="Center"
                Width="145"
                TextChanged="nameFilterTextBox_TextChanged">
                <telerik:RadWatermarkTextBox.WatermarkContent>
                    <TextBlock VerticalAlignment="Center"
                   Text="{Binding Path=CommonTranslations.txtHierarchyFilter, Source={StaticResource TranslationsManager}}"
                   FontStyle="Italic" />
                </telerik:RadWatermarkTextBox.WatermarkContent>
            </telerik:RadWatermarkTextBox>
        </StackPanel>
         
        <telerik:RadTreeView x:Name="FiltersTreeView" Margin="3" Grid.Row="1" 
                         IsOptionElementsEnabled="True"
                         IsTriStateMode="True"
                         ScrollViewer.VerticalScrollBarVisibility="Visible"      
                         ItemPrepared="FiltersTreeView_ItemPrepared"
                         ItemTemplate="{StaticResource ItemTemplate}"
                         ItemsSource="{Binding Converter={StaticResource FilterHierarchyConverter}}"
                         >
            <telerik:RadTreeView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel />
                </ItemsPanelTemplate>
            </telerik:RadTreeView.ItemsPanel>
        </telerik:RadTreeView>
 
        <Border Grid.Row="2" Margin="3" BorderBrush="LightGray" BorderThickness="1">
            <StackPanel Margin="0,0,5,5" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right">
                <telerik:RadButton Name="btnAccept" Cursor="Hand" Content="{Binding Path=CommonTranslations.btnAccept, Source={StaticResource TranslationsManager}}" Click="btnAccept_Click" />
                <telerik:RadButton Name="btnCancel" Cursor="Hand" Content="{Binding Path=CommonTranslations.btnCancel, Source={StaticResource TranslationsManager}}" Click="btnCancel_Click" Margin="5,0,0,0" />
            </StackPanel>
        </Border>
    </Grid>
</UserControl>

C# code: 

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
using Test.common;
using Test.model.binding;
using Test.model.filterview;
using Test.model.product;
 
using Telerik.Windows.Controls;
using Test.resources;
 
namespace Test.widgets.dialogs
{
    /// <summary>
    /// The filters tree view uc.
    /// </summary>
    public partial class FiltersTreeViewUC : UserControl
    {
        /// <summary>
        /// Denormalized tree items
        /// </summary>
        private ObservableCollection<FilterTreeItem> items = null;
 
        /// <summary>
        /// Original tree items
        /// </summary>
        //private ObservableCollection<FilterTreeItem> originalItems = null;
 
        /// <summary>
        /// Root hierarchy node
        /// </summary>
        private FilterRefHierarchy rootHierarchy = null;
 
        /// <summary>
        /// Denormalized names of the tree hierarchy
        /// </summary>
        private List<String> denormalizedHierarchyNames = null;
 
        /// <summary>
        /// Denoramlized filters hierarchies
        /// </summary>
        private List<DashBoardFilter> denormalizedFiltersHierarchies = null;
 
        /// <summary>
        /// Denormalized filter references
        /// </summary>
        private List<DashBoardFilterRef> denormalizedFilterRefs = null;
 
        /// <summary>
        /// The dashboard delegate
        /// </summary>
        private DashBoardDelegate dashBoardDelegate = null;
 
        /// <summary>
        /// Selected filters and values
        /// </summary>
        private Dictionary<DashBoardFilterRef, List<String>> selectedFilterMap = null;
 
        /// <summary>
        /// List of seleted values
        /// </summary>
        private List<string> seletedValuesNames = null;
 
        /// <summary>
        /// Current selected value
        /// </summary>
        private String selectedValue = string.Empty;
 
        /// <summary>
        /// Current group selected index
        /// </summary>
        private int currentSelectionLevel = -1;
 
        /// <summary>
        /// Current filter text size
        /// </summary>
        private int currentFilterTextSize = 0;
 
        /// <summary>
        /// Parent dialog window
        /// </summary>
        public RadWindow ParentWindow { get; set; }
 
        /// <summary>
        /// Event handler to close window
        /// </summary>
        /// <param name="sender">
        /// The sender
        /// </param>
        /// <param name="filterRefSelected">
        /// The selected filter
        /// </param>
        /// <param name="refHierarchy">
        /// Filter hierarchy
        /// </param>
        /// <param name="selectedValues">
        /// Selected values
        /// </param>
        /// <param name="selectedValuesNames">
        /// Selected values names
        /// </param>
        public delegate void OnAcceptReturnHandler(object sender, DashBoardFilterRef filterRefSelected,
            FilterRefHierarchy refHierarchy, List<String> selectedValues, List<String> selectedValuesNames);
 
        /// <summary>
        /// On Accept Return handler
        /// </summary>
        public event OnAcceptReturnHandler OnAccept;
 
        /// <summary>
        /// Sender object
        /// </summary>
        private object sender = null;
 
        /// <summary>
        /// Class constructor
        /// </summary>
        public FiltersTreeViewUC()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// Parametrized constructor
        /// </summary>
        /// <param name="items">
        /// The tree items
        /// </param>
        /// <param name="rootHierarchy">
        /// Root hierarchy
        /// </param>
        /// <param name="selectedFilterMap">
        /// Selected filter map
        /// </param>
        /// <param name="dashBoardDelegate">
        /// The dashboard delegatre
        /// </param>
        /// <param name="sender">
        /// The sender object
        /// </param>
        public FiltersTreeViewUC(ObservableCollection<FilterTreeItem> items, FilterRefHierarchy rootHierarchy,
            Dictionary<DashBoardFilterRef, List<String>> selectedFilterMap, DashBoardDelegate dashBoardDelegate,
            object sender)
        {
            InitializeComponent();
 
            // Copy of the original
            /*this.originalItems = items;
            this.items = new ObservableCollection<FilterTreeItem>();
            foreach (FilterTreeItem fti in items)
            {
                this.items.Add(fti.getCopy());
            }*/
            this.items = items;
            this.sender = sender;           
 
            this.rootHierarchy = rootHierarchy;
 
            this.denormalizedHierarchyNames = new List<string>();
            this.denormalizedFiltersHierarchies = new List<DashBoardFilter>();
            this.denormalizedFilterRefs = new List<DashBoardFilterRef>();
 
            this.dashBoardDelegate = dashBoardDelegate;
            this.selectedFilterMap = selectedFilterMap;
 
            this.denormalizeHierarchy(rootHierarchy);
 
            // Calculate the current selection level
            this.getSelectionLevel(this.items);
 
            this.cmbGroups.ItemsSource = this.denormalizedHierarchyNames;
            if (this.currentSelectionLevel < 0)
            {
                this.currentSelectionLevel = 0;
            }
             
            this.cmbGroups.SelectedIndex = this.currentSelectionLevel;
 
            // Load the data
            this.refreshTree(this.currentSelectionLevel);           
 
            // Event Item click
            // FiltersTreeView.Checked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(FiltersTreeView_Checked);
            // FiltersTreeView.Unchecked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(FiltersTreeView_Unchecked);
        }
 
        /// <summary>
        /// Filterstree unchecked method
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arg</param>
        public void FiltersTreeView_Unchecked(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTreeViewItem radTreeViewItem = e.Source as RadTreeViewItem;
            FilterTreeItem fti = radTreeViewItem.Item as FilterTreeItem;           
             
            if ((radTreeViewItem.CheckState != System.Windows.Automation.ToggleState.Indeterminate) && (fti != null) && (FiltersTreeView.SelectionMode == Telerik.Windows.Controls.SelectionMode.Multiple))
            {
                // Depending on check state and selection mode, check & uncheck children
                uncheckAllChildrenRecursively(fti);
            }
        }
 
        /// <summary>
        /// Filterstree checked method
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arg</param>
        public void FiltersTreeView_Checked(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTreeViewItem radTreeViewItem = e.Source as RadTreeViewItem;
            FilterTreeItem fti = radTreeViewItem.Item as FilterTreeItem;
 
            if ((radTreeViewItem.CheckState != System.Windows.Automation.ToggleState.Indeterminate) && (fti != null) && (FiltersTreeView.SelectionMode == Telerik.Windows.Controls.SelectionMode.Multiple))
            {
                // Depending on check state and selection mode, check & uncheck children
                checkAllChildrenRecursively(fti);               
            }       
        }
        /*
        private FilterTreeItem findTreeItemInOriginal(ObservableCollection<FilterTreeItem> source, FilterTreeItem toFind)
        {
            foreach (FilterTreeItem fti in source)
            {
                if (fti.Text.Equals(toFind.Text) && fti.FilterRef.Equals(toFind.FilterRef))
                {
                    return fti;
                }
                if (fti.Children != null)
                {
                    FilterTreeItem child = findTreeItemInOriginal(fti.Children,toFind);
                    if(child != null)
                    {
                        return child;
                    }
                }
            }
            return null;
        }*/
 
        /// <summary>
        /// Metjpd tp check all children recursively
        /// </summary>
        /// <param name="fti">The parent node to check</param>
        private void checkAllChildrenRecursively(FilterTreeItem fti)
        {
            if (fti.Children != null)
            {
                foreach (FilterTreeItem child in fti.Children)
                {
                    child.Checked = true;
                    if (child.Children != null)
                    {
                        checkAllChildrenRecursively(child);
                    }
                }
            }                
        }
 
        /// <summary>
        /// Method to uncheck all children recursively
        /// </summary>
        /// <param name="fti">The parent node</param>
        private void uncheckAllChildrenRecursively(FilterTreeItem fti)
        {
            if (fti.Children != null)
            {
                foreach (FilterTreeItem child in fti.Children)
                {
                    child.Checked = false;
                    if (child.Children != null)
                    {
                        uncheckAllChildrenRecursively(child);
                    }
                }
            }                
        }
 
        /// <summary>
        /// Method to calc the current selection level based on the selected elements
        /// </summary>
        /// <param name="treeItems">
        /// Tree items loaded
        /// </param>
        private void getSelectionLevel(ObservableCollection<FilterTreeItem> treeItems)
        {
            foreach (FilterTreeItem fti in treeItems)
            {
                // Get the filter selection level
                if (this.selectedFilterMap.ContainsKey(fti.FilterRef)
                    && (this.selectedFilterMap[fti.FilterRef].Count > 0)
                    && (this.selectedFilterMap[fti.FilterRef].Count > 0))
                {
                    // Select the deepest level
                    if (fti.TreeLevel > this.currentSelectionLevel)
                    {
                        this.currentSelectionLevel = fti.TreeLevel;
                    }
 
                    // Now check the corresponding elements
                    List<String> selectedNodeValues = this.selectedFilterMap[fti.FilterRef];
                    fti.Checked = selectedNodeValues.Contains(fti.Value);
 
                }
 
                if ((fti.Children != null) && (fti.Children.Count > 0))
                {
                    this.getSelectionLevel(fti.Children);
                }
            }
        }
 
        /// <summary>
        /// Method to denormalize hierarchy
        /// </summary>
        /// <param name="rootNode">
        /// FilterRefHierarchy node
        /// </param>
        private void denormalizeHierarchy(FilterRefHierarchy rootNode)
        {
            DashBoardFilter filterDefinition =
                this.dashBoardDelegate.CurrentDashBoardDefinition.Filters[rootNode.FilterRef.UuId];
            this.denormalizedHierarchyNames.Add(filterDefinition.DefaultName);
            this.denormalizedFiltersHierarchies.Add(filterDefinition);
            this.denormalizedFilterRefs.Add(rootNode.FilterRef);
 
            // If there is no data at one specific level then
            if ((rootNode.Child != null)
                && ((!this.selectedFilterMap.ContainsKey(rootNode.FilterRef))
                    || (this.selectedFilterMap[rootNode.FilterRef].Count == 0)))
            {
                this.denormalizeHierarchy(rootNode.Child);
            }
            else
            {
                if (this.selectedFilterMap.ContainsKey(rootNode.FilterRef)
                    && (this.selectedFilterMap[rootNode.FilterRef].Count > 0))
                {
                    this.selectedValue = rootNode.FilterRef.UuId;
                }
 
                if (rootNode.Child != null)
                {
                    this.denormalizeHierarchy(rootNode.Child);
                }
            }
        }
 
        /// <summary>
        /// The btn accept_ click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void btnAccept_Click(object sender, RoutedEventArgs e)
        {
            // Get the selected items on tree
            Dictionary<DashBoardFilterRef, List<String>> selectedValueMap =
                new Dictionary<DashBoardFilterRef, List<string>>();
 
            this.seletedValuesNames = new List<string>();
 
            foreach (FilterTreeItem item in this.items)
            {
                this.assignSelectedValues(item, selectedValueMap);
            }
 
            // Close the window and launch event             
            if (selectedValueMap.Keys.Count > 0)
            {
                OnAccept(this.sender, selectedValueMap.Keys.ToArray()[0],
                    rootHierarchy, selectedValueMap[selectedValueMap.Keys.ToArray()[0]], seletedValuesNames);
            }
            else
            {
                // Return empty selection
                DashBoardFilterRef selectedFilterRef = (this.currentSelectionLevel >= 0)
                                                           ? this.denormalizedFilterRefs[this.currentSelectionLevel]
                                                           : this.rootHierarchy.FilterRef;
                OnAccept(this.sender, selectedFilterRef, this.rootHierarchy, new List<String>(), new List<String>());
            }
 
            ParentWindow.Close();
        }
 
        /// <summary>
        /// Method to assign the selected values to the map depending on the "check" state of
        /// one item and the current max selection level
        /// </summary>
        /// <param name="fti">
        /// Filter tree item
        /// </param>
        /// <param name="selectedValueMap">
        /// Map with the selection values
        /// </param>
        private void assignSelectedValues(FilterTreeItem fti,
            Dictionary<DashBoardFilterRef, List<String>> selectedValueMap)
        {
            if (fti.TreeLevel == this.currentSelectionLevel)
            {
                // Assign selected value if it's checked
                if (fti.Checked)
                {
                    if (!selectedValueMap.ContainsKey(fti.FilterRef))
                    {
                        selectedValueMap.Add(fti.FilterRef, new List<string>());
                    }
 
                    List<String> selectedValues = selectedValueMap[fti.FilterRef];
                    selectedValues.Add(fti.Value);
                    seletedValuesNames.Add(fti.Text);
                }
 
                return;
            }
            else if (fti.TreeLevel < this.currentSelectionLevel)
            {
                foreach (FilterTreeItem child in fti.Children)
                {
                    this.assignSelectedValues(child, selectedValueMap);
                }
            }
 
            return;
        }
 
        /// <summary>
        /// The btn cancel_ click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            ParentWindow.Close();
        }
 
        /// <summary>
        /// The cmb groups_ selection changed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void cmbGroups_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
        {
            int selectedIndex = this.cmbGroups.SelectedIndex;
 
            // Substract 1 to erase the "Select" element
            this.refreshTree(selectedIndex);
        }
 
        /// <summary>
        /// Method to refresh a tree
        /// </summary>
        /// <param name="selectedLevel">
        /// Selected level index
        /// </param>
        private void refreshTree(int selectedLevel)
        {
            Telerik.Windows.Controls.HierarchicalDataTemplate treeTemplate = (Telerik.Windows.Controls.HierarchicalDataTemplate)FiltersTreeView.ItemTemplate;
            FilterHierarchyConverter converter = (FilterHierarchyConverter)treeTemplate.ItemsSource.Converter;
 
            converter.MaxLevel = selectedLevel;
            this.currentSelectionLevel = selectedLevel;
 
            // Reload the items
            FiltersTreeView.ItemsSource = null;
            FiltersTreeView.ItemsSource = this.items;
            FiltersTreeView.UpdateLayout();
 
            // Enable/disable multiselect
            if (selectedLevel >= 0)
            {
                if (this.denormalizedFiltersHierarchies[selectedLevel].IsMultiSelect)
                {
                    FiltersTreeView.SelectionMode = Telerik.Windows.Controls.SelectionMode.Multiple;
                    FiltersTreeView.ItemsOptionListType = OptionListType.CheckList;                   
                }
                else
                {
                    FiltersTreeView.SelectionMode = Telerik.Windows.Controls.SelectionMode.Single;
                    FiltersTreeView.ItemsOptionListType = OptionListType.OptionList;
                }
            }
        }
 
        /// <summary>
        /// The none label_ mouse left button up.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void NoneLabel_OnMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            foreach (FilterTreeItem item in this.items)
            {
                this.desAssignSelectedValues(item);
            }
 
            // Reload the items
            FiltersTreeView.ItemsSource = null;
            FiltersTreeView.ItemsSource = this.items;
        }
 
        /// <summary>
        /// Desassign all Selected Values
        /// </summary>
        /// <param name="fti">FilterTreeItem</param>
        private void desAssignSelectedValues(FilterTreeItem fti)
        {
            fti.Checked = false;
            if (fti.Children != null && fti.Children.Count() > 0)
            {
                foreach (FilterTreeItem item in fti.Children)
                {
                    this.desAssignSelectedValues(item);
                }
            }
 
            return;
        }
 
        /// <summary>
        /// Has Children Checked
        /// </summary>
        /// <param name="fti">FilterTreeItem</param>
        /// <returns>Bool</returns>
        public bool hasChildrenChecked(FilterTreeItem fti)
        {
            if (fti.Children == null)
            {
                return false;
            }
 
            foreach (FilterTreeItem child in fti.Children)
            {
                if (child.Checked)
                {
                    return true;
                }
            }
 
            foreach (FilterTreeItem child in fti.Children)
            {
                if (hasChildrenChecked(child))
                {
                    return true;
                }
            }
 
            return false;
        }
 
        /// <summary>
        /// FiltersTreeView_ItemPrepared Event
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">RadTreeViewItemPreparedEventArgs</param>
        private void FiltersTreeView_ItemPrepared(object sender, RadTreeViewItemPreparedEventArgs e)
        {
            e.PreparedItem.CheckState = (e.PreparedItem.Item as FilterTreeItem).Checked ? System.Windows.Automation.ToggleState.On : System.Windows.Automation.ToggleState.Off;
 
            FilterTreeItem fti = e.PreparedItem.Item as FilterTreeItem;
 
            if (hasChildrenChecked(fti))
            {
                if (fti.TreeLevel < this.currentSelectionLevel)
                {
                    e.PreparedItem.CheckState = System.Windows.Automation.ToggleState.Indeterminate;
                }
                else
                {
                    e.PreparedItem.CheckState = System.Windows.Automation.ToggleState.On;
                }
            }
 
            e.PreparedItem.Checked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(PreparedItem_Checked);
            e.PreparedItem.Unchecked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(PreparedItem_Unchecked);
        }
 
        /// <summary>
        /// PreparedItem_Unchecked Event
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">RadRoutedEventArgs</param>
        private void PreparedItem_Unchecked(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTreeViewItem item = sender as RadTreeViewItem;
 
            if ((item != null) && (item.CheckState == System.Windows.Automation.ToggleState.Off))
            {
                (item.Item as FilterTreeItem).Checked = false;
                uncheckAllChildrenRecursively(item.Item as FilterTreeItem);
                /*FilterTreeItem fti_original = findTreeItemInOriginal(this.originalItems, item.Item as FilterTreeItem);
                fti_original.Checked = true;
                uncheckAllChildrenRecursively(fti_original);*/
            }
        }
 
        /// <summary>
        /// PreparedItem_Checked Event
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">RadRoutedEventArgs</param>
        private void PreparedItem_Checked(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTreeViewItem item = sender as RadTreeViewItem;
 
            if ((item != null) && (item.CheckState == System.Windows.Automation.ToggleState.On))
            {
                (item.Item as FilterTreeItem).Checked = true;
                 
                // Depending on check state and selection mode, check & uncheck children
                checkAllChildrenRecursively(item.Item as FilterTreeItem);
                /*FilterTreeItem fti_original = findTreeItemInOriginal(this.originalItems, item.Item as FilterTreeItem);
                fti_original.Checked = true;
                checkAllChildrenRecursively(fti_original);*/
            }
        }
 
        /// <summary>
        /// nameFilterTextBox_TextChanged Event
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">TextChangedEventArgs</param>
        private void nameFilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!String.IsNullOrEmpty(nameFilterTextBox.Text) &&
                nameFilterTextBox.Text != CommonTranslations.ResourceManager.GetString("txtHierarchyFilter"))
            {
                //FiltersTreeView.ItemsSource = this.items.Where(i => i.Text.Contains(nameFilterTextBox.Text));
                FilterCollection(this.items, nameFilterTextBox.Text, this.currentSelectionLevel,0);
            }
            else
            {
                resetVisibility(this.items);
            }
            FiltersTreeView.ItemsSource = null;
            FiltersTreeView.ItemsSource = this.items;
            FiltersTreeView.ExpandAll();
            this.currentFilterTextSize = nameFilterTextBox.Text.Length;
        }
 
        /// <summary>
        /// FilterCollection
        /// </summary>
        /// <param name="collection">Collection to filter</param>
        /// <param name="filterText">Filter text</param>
        private void FilterCollection(ObservableCollection<FilterTreeItem> collection, string filterText,int tillLevel, int currentLevel)
        {
            if( currentLevel > tillLevel)
            {
                return;
            }           
            foreach (FilterTreeItem treeItem in collection)
            {
                if (currentLevel < tillLevel && treeItem.Children != null)
                {
                    FilterCollection(treeItem.Children, filterText, tillLevel, currentLevel + 1);
                    if (treeItem.Children.Count == 0)
                    {
                        treeItem.IsVisible = Visibility.Collapsed; //removedTreeItems.Add(treeItem);
                    }
                }
                if (currentLevel == tillLevel && !treeItem.Text.ToLower().Contains(filterText.ToLower()))
                {
                    treeItem.IsVisible = Visibility.Collapsed; //removedTreeItems.Add(treeItem);
                }
                else
                {
                    treeItem.IsVisible = Visibility.Visible;
                }
            }
        }
        /// <summary>
        /// Recursively sets vibility to "Visible" state of all nodes in collection
        /// </summary>
        /// <param name="collection">Collection</param>
        private void resetVisibility(ObservableCollection<FilterTreeItem> collection)
        {
            foreach (FilterTreeItem treeItem in collection)
            {
                treeItem.IsVisible = Visibility.Visible;
                if (treeItem.Children != null)
                {
                    resetVisibility(treeItem.Children);
                }
            }
        }
 
        /*
        private ObservableCollection<FilterTreeItem> duplicateTreeWithSelectionFromTarget(ObservableCollection<FilterTreeItem> source, FilterTreeItem parent, ObservableCollection<FilterTreeItem> target)
        {
            ObservableCollection<FilterTreeItem> toRet = new ObservableCollection<FilterTreeItem>();
            foreach (FilterTreeItem fti_s in source)
            {
                toRet.Add(fti_s.getCopy(parent));
            }
            foreach (FilterTreeItem fti_t in target)
            {
                foreach (FilterTreeItem fti_r in toRet)
                {
                    if (fti_r.Text.Equals(fti_t.Text) && fti_r.FilterRef.Equals(fti_t.FilterRef))
                    {
                        fti_r.Checked = fti_t.Checked;
                        if (fti_t.Children != null)
                        {
                            fti_r.Children = duplicateTreeWithSelectionFromTarget(fti_r.Children, fti_r, fti_t.Children);
                        }                       
                        break;
                    }
                }
            }
            return toRet;
        }*/
    }
}
0
Petar Mladenov
Telerik team
answered on 22 May 2013, 09:09 AM
Hello Carlos,

 You have to set the Visibility of RadTreeViewItems via Style, not on the TextBlock in the template:

<Grid.Resources>
           <Style TargetType="telerik:RadTreeViewItem">
               <Setter Property="ItemsPanel">
                   <Setter.Value>
                       <ItemsPanelTemplate>
                           <StackPanel />
                       </ItemsPanelTemplate>
                   </Setter.Value>
               </Setter>
               <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource boolToVisConverter}}" />
           </Style>
       </Grid.Resources>
Some notes here:
1) This is demonstrated in the attached project for WPF.
2) Style bindings work for WPF and SL 5.
3) If you use SL 4 (I guess you use it since you use Container Bindings), use Container Binding, not Style Bindings.
4) Note the converter which converts Boolean property to Visibility property.
5) You can send us support tickets instead of forum post. This way you will be able attach files and a 24 hour reply is guaranteed. Please specify whether you use WPF or SL. Regards,
Petar Mladenov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Carlos
Top achievements
Rank 1
answered on 22 May 2013, 04:07 PM
Thank you very much for your help. Everything is working as intended :)
0
Itamar
Top achievements
Rank 1
answered on 05 Dec 2013, 02:34 PM
Hello,
In the release notes of Q3 2013 version and in yours PITS this issue was marked as resolved.
I'm using this version (Q3 2013 - 2013.3.1016.40), and it seams that this issue was not resolved.
Although the root items visibility are collapsed properly (just like in the old versions), the child nodes are still being hidden instead of collapsed, which causes blank areas to appear in the tree.

I'm open a support ticket (Number 765581).

This is the code sample that reproduces the problem:

<telerik:RadTreeView>
            <telerik:RadTreeViewItem Header="Item A" />
            <telerik:RadTreeViewItem Header="Item B" >
                <telerik:RadTreeViewItem Header="Item B1" />
                <telerik:RadTreeViewItem Header="Item B2" Visibility="Collapsed"/>
                <telerik:RadTreeViewItem Header="Item B3" />
            </telerik:RadTreeViewItem>
            <telerik:RadTreeViewItem Header="Item C" Visibility="Collapsed"/>
            <telerik:RadTreeViewItem Header="Item D" >
                <telerik:RadTreeViewItem Header="Item D1" />
                <telerik:RadTreeViewItem Header="Item D2" Visibility="Collapsed"/>
                <telerik:RadTreeViewItem Header="Item D3" />
            </telerik:RadTreeViewItem>
            <telerik:RadTreeViewItem Header="Item E" />
            <telerik:RadTreeViewItem Header="Item F" />
        </telerik:RadTreeView>

Please let me know if i'm doing something wrong. if not please suggest a  work around.

Regards,
Itamar.

1
Petar Mladenov
Telerik team
answered on 06 Dec 2013, 02:39 PM
Hi Itamar,

We created a separate property for such scenarios - ItemVisibility. Please use it instead of Visibility and the problematic space will disappear.

Regards,
Petar Mladenov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Itamar
Top achievements
Rank 1
answered on 08 Dec 2013, 07:30 AM
Thank you!
0
s
Top achievements
Rank 1
answered on 20 Apr 2021, 09:11 AM
Hi, can you give some examples about how to use ItemVisibility? In a TreeView, i design its ItemTemplate. A StackPanel contains three controls,  but the Visibility.Collpsed of StackPanel has space. Hope your help, thanks!
0
Petar Mladenov
Telerik team
answered on 20 Apr 2021, 09:31 AM

Hello,

Its a direct property of RadTreeViewItem and cannot be set to other elements. In a databinding scenario properties of RadTreeViewItems can be set via Style setters directly bound to properties from your viewmodels. Here is an article demonstrating such style bindings:

https://docs.telerik.com/devtools/wpf/controls/radtreeview/how-to/bind-selected-item

 

Regards,
Petar Mladenov
Progress Telerik

Тhe web is about to get a bit better! 

The Progress Hack-For-Good Challenge has started. Learn how to enter and make the web a worthier place: https://progress-worthyweb.devpost.com.

Tags
TreeView
Asked by
Kennet
Top achievements
Rank 2
Answers by
Miroslav
Telerik team
Aurore
Top achievements
Rank 1
Hristo
Telerik team
Tina Stancheva
Telerik team
Tom
Top achievements
Rank 1
Rob Peters
Top achievements
Rank 1
Petar Mladenov
Telerik team
Brent
Top achievements
Rank 2
Gonzalo
Top achievements
Rank 1
Carlos
Top achievements
Rank 1
Itamar
Top achievements
Rank 1
s
Top achievements
Rank 1
Share this question
or