ContainerBinding Visibility problem

4 posts, 0 answers
  1. Serhiy Volhushyn
    Serhiy Volhushyn avatar
    21 posts
    Member since:
    Dec 2009

    Posted 11 Dec 2009 Link to this post

    Build 2009.3.1208 It looks like Visibility ContainerBinding does not work properly.

    XAML Source:

    <UserControl  
        x:Class="RadTreeViewTest.MainPage" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:RadNavigation="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" 
        xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls" 
        > 
     
        <UserControl.Resources> 
            <telerik:ContainerBindingCollection x:Key="NodeBindings">  
                <telerik:ContainerBinding PropertyName="Visibility" Binding="{Binding Visibility, Mode=TwoWay}" /> 
            </telerik:ContainerBindingCollection> 
     
            <telerik:HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding Nodes}" telerik:ContainerBinding.ContainerBindings="{StaticResource NodeBindings}">  
                <TextBlock Text="{Binding Text}" VerticalAlignment="Center" Margin="3,0,0,0" Visibility="{Binding Visibility}" /> 
            </telerik:HierarchicalDataTemplate> 
        </UserControl.Resources> 
     
        <Grid> 
            <Grid.RowDefinitions> 
                <RowDefinition Height="Auto" /> 
                <RowDefinition Height="Auto" /> 
            </Grid.RowDefinitions> 
     
            <TextBox  
                Name="SearchTextBox" 
                Grid.Row="0" 
                Width="200" 
                TextChanged="SearchTextBox_OnTextChanged" 
                /> 
     
            <RadNavigation:RadTreeView  
                Name="testTreeView" 
                ItemTemplate="{StaticResource NodeTemplate}" 
                Grid.Row="1" 
                Margin="0,5,0,0" 
                Width="200" 
                Height="350" 
                BorderBrush="Black" 
                BorderThickness="1" 
                /> 
        </Grid> 
     
    </UserControl> 

    C# Source:

    using System.Collections.Generic;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Globalization;  
    using System.Windows;  
    using System.Windows.Controls;  
     
    namespace RadTreeViewTest  
    {  
        public partial class MainPage  
        {  
            private readonly List<ApplicationMenuNode> _nodes;  
     
            public MainPage()  
            {  
                InitializeComponent();  
     
                _nodes = CreateSource();  
     
                testTreeView.ItemsSource = _nodes;  
            }
            #region private static CreateSource  
            private static List<ApplicationMenuNode> CreateSource()  
            {  
                List<ApplicationMenuNode> rez = new List<ApplicationMenuNode>();  
     
                for (int nodeNum = 1; nodeNum < 6; nodeNum++)  
                {  
                    ApplicationMenuNode node = new ApplicationMenuNode  
                                                {  
                                                    Text = string.Format(CultureInfo.CurrentUICulture, "Node {0}", nodeNum),  
                                                };  
     
                    for (int subNodeNum = 1; subNodeNum < 6; subNodeNum++)  
                    {  
                        node.Nodes.Add(new ApplicationMenuNode  
                                        {  
                                            Text = string.Format(CultureInfo.CurrentUICulture, "Node {0}.{1}", nodeNum, subNodeNum),  
                                        });  
                    }  
     
                    rez.Add(node);  
                }  
     
                return rez;  
            }
            #endregion  
     
            #region private void SearchTextBox_OnTextChanged  
            private void SearchTextBox_OnTextChanged(object sender, TextChangedEventArgs e)  
            {  
                foreach (ApplicationMenuNode node in _nodes)  
                {  
                    node.FilterByText(SearchTextBox.Text);  
                }  
     
                testTreeView.ExpandAll();  
            }
            #endregion  
        }  
     
        public class ApplicationMenuNode : INotifyPropertyChanged  
        {
            #region Properties  
            public event PropertyChangedEventHandler PropertyChanged;  
     
            public string Text { getset; }  
     
            private Visibility _visibility = Visibility.Visible;  
            public Visibility Visibility  
            {  
                get { return _visibility; }  
                set 
                {  
                    if (_visibility != value)  
                    {  
                        _visibility = value;  
                        InvokePropertyChanged(new PropertyChangedEventArgs("Visibility"));  
                    }  
                }  
            }  
     
            private readonly ObservableCollection<ApplicationMenuNode> _nodes = new ObservableCollection<ApplicationMenuNode>();  
            public ObservableCollection<ApplicationMenuNode> Nodes { get { return _nodes; } }
            #endregion  
     
     
            #region private InvokePropertyChanged  
            private void InvokePropertyChanged(PropertyChangedEventArgs e)  
            {  
                PropertyChangedEventHandler Handler = PropertyChanged;  
     
                if (Handler != null)  
                {  
                    Handler(this, e);  
                }  
            }
            #endregion  
     
     
            #region public FilterByText  
            public bool FilterByText(string text)  
            {  
                bool isAnyChildVisible = (Nodes.Count == 0);  
     
                foreach (ApplicationMenuNode node in _nodes)  
                {  
                    bool isChildVisibile = node.FilterByText(text);  
     
                    isAnyChildVisible = isAnyChildVisible || isChildVisibile;  
                }  
     
                bool isVisible;  
     
                if (string.IsNullOrEmpty(text) || (Text != null && Text.ToUpper(CultureInfo.CurrentCulture).Contains(text.ToUpper(CultureInfo.CurrentCulture))))  
                {  
                    isVisible = isAnyChildVisible;  
                }  
                else 
                {  
                    isVisible = ((_nodes.Count != 0) && isAnyChildVisible);  
                }  
     
                Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed;  
     
                return isVisible;  
            }
            #endregion  
        }  
    }  
     

    Compile and run. enter ".2" in the text box and you can see empty spaces inside TreeView.

    Screenshot

    It looks like a bug. Is there any workaround for now and can it, please, be fixed ?
  2. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 13 Dec 2009 Link to this post

    Hi Serhiy Volhushyn,

    This is a known limitation of the new virtualizing TreeViewPanel. We did not expect that this will be a very common case. If there is demand, we can look into enabling this binding with the new virtualizing panel.

    To revert back to how the TreeView used to work, you can replace the ItemsPanel of the TreeView and its items with a StackPanel (the panel that was used before the Q3 release).

    Collapsing the TreeViewItems is the fastest way to achieve filtering "look" but then things like lines, checkboxes and selection may not work as expected. If you want to filter the TreeView and preserve its functionality, I can suggest removing the items from their collection instead of collapsing them.

    Greetings,

    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.
  3. DevCraft banner
  4. Roman
    Roman avatar
    1 posts
    Member since:
    Oct 2010

    Posted 14 Oct 2010 Link to this post

    Hello,
    I think nothing changes so far as I just hit the same problem with the latest version. For some reasons I don't want to filter my data but hide items in the tree. Could you send an example how can I replace ItemsPanel because when I write

    <telerik:RadTreeView bla-bla-bla >
                    <telerik:RadTreeView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel></StackPanel>
                        </ItemsPanelTemplate>
                    </telerik:RadTreeView.ItemsPanel>
                </telerik:RadTreeView>

    I get only first level items but nothing if I expand them.
    Thanks.
  5. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 18 Oct 2010 Link to this post

    Hi Roman,

    Can you please try to set the ItemsPanel property via style on both RadTreeView and RadTreeViewItems.
    Following code snippet describes what I mean:

    XAML:

    <UserControl.Resources>
        <Style TargetType="telerik:RadTreeView">
            <Style.Setters>
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <StackPanel/>
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
     
        <Style TargetType="telerik:RadTreeViewItem">
            <Style.Setters>
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <StackPanel/>
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
     
        <telerik:HierarchicalDataTemplate x:Key="TreeViewItemTemplate" ItemsSource="{Binding Items}">
            <TextBlock Text="{Binding Name}"/>
        </telerik:HierarchicalDataTemplate>
             
    </UserControl.Resources>
         
    <StackPanel Background="White">
        <telerik:RadTreeView Name="SampletreeView">
            <telerik:RadTreeViewItem Header="Item 1">
                <telerik:RadTreeViewItem Header="Item 1.1">
                    <telerik:RadTreeViewItem Header="Item 1.1.1"/>
                    <telerik:RadTreeViewItem Header="Item 1.1.2"/>
                    <telerik:RadTreeViewItem Header="Item 1.1.3"/>
                </telerik:RadTreeViewItem>
                <telerik:RadTreeViewItem Header="Item 1.2"/>
                <telerik:RadTreeViewItem Header="Item 1.3"/>
            </telerik:RadTreeViewItem>
            <telerik:RadTreeViewItem Header="Item 2">
                <telerik:RadTreeViewItem Header="Item 2.1"/>
                <telerik:RadTreeViewItem Header="Item 2.2"/>
            </telerik:RadTreeViewItem>
        </telerik:RadTreeView>
     
        <telerik:RadTreeView Name="SampletreeViewDataBound" ItemsSource="{Binding .}" ItemTemplate="{StaticResource TreeViewItemTemplate}"/>
             
    </StackPanel>

    C#:

    public partial class MainPage : UserControl
        {
            private SampleViewModel sampleVM = new SampleViewModel();
     
            public MainPage()
            {
                InitializeComponent();
                this.DataContext = this.sampleVM;
            }
        }
     
        public class SampleViewModel : ObservableCollection<BusinessItem>
        {
            public SampleViewModel()
            {
                BusinessItem bi;
                bi = new BusinessItem("Item 1");
                bi.Items.Add(new BusinessItem("Item 2"));
                bi.Items.Add(new BusinessItem("Item 3"));
                bi.Items.Add(new BusinessItem("Item 4"));
                this.Add(bi);
                bi.Items[0].Items.Add(new BusinessItem("Leaf 1"));
                bi.Items[0].Items.Add(new BusinessItem("Leaf 2"));
                bi.Items[0].Items.Add(new BusinessItem("Leaf 3"));
     
                bi = new BusinessItem("Item 5");
                bi.Items.Add(new BusinessItem("Item 6"));
                bi.Items.Add(new BusinessItem("Item 7"));
                bi.Items.Add(new BusinessItem("Item 8"));
                this.Add(bi);
     
                bi = new BusinessItem("Item 9");
                this.Add(bi);
                bi = new BusinessItem("Item 10");
                this.Add(bi);
                bi = new BusinessItem("Item 11");
                this.Add(bi);
     
            }
        }
     
        public class BusinessItem
        {
            public BusinessItem(string name)
            {
                this.Name = name;
                this.Items = new ObservableCollection<BusinessItem>();
            }
     
            public string Name { get; set; }
     
            public ObservableCollection<BusinessItem> Items { get; set; }
        }

    Hope this helps. Please let me know if the provided solution does not work in your case.


    Sincerely yours,
    Hristo
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top