How can I access the checkboxes with a XML databound RadTreeView?

3 posts, 1 answers
  1. Johan Van der Galien
    Johan Van der Galien avatar
    6 posts
    Member since:
    Mar 2010

    Posted 25 Jan 2011 Link to this post

    How can I access the checkboxes with a XML databound RadTreeView?

    Dear Madam or Sir,

    What I try or do I never get up the tree! Also I suspect that ChilderenByType() is not capable to give you access to all CheckBox nodes. Not even layer-by-layer.

    (I know the proper way is a recursive function)

    But I see no other way than to roll out the recursion because I got the XMLNodeItems separate from the (ItemsOptionListType="CheckList") checkboxes and I must set IsChecked = true for the CheckBoxes with a value saved in the database. When I can get up the tree the next challenge to keep the visual tree (correct checkboxes checked) in sync with what the user saved.

    WHY DOES MY CODE NOT WORK AND WHAT SHOULD I DO?

    XAML

    <telerik:RadWindow x:Class="Jbusiness.Views.Gegevens.AdviseurTreeView"
        xmlns:local="clr-namespace:Jbusiness.Views.Gegevens"            
        xmlns:telerik2="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"
        mc:Ignorable="d"
        Height="800" Width="400">
        <telerik:RadWindow.Resources>
            <local:RadTreeViewXmlDataSource x:Key="treeViewData" Source="ItemsXML.xml"/>
            <telerik:HierarchicalDataTemplate x:Key="Item" ItemsSource="{Binding Items}">
                <TextBlock Text="{Binding Header}" />
            </telerik:HierarchicalDataTemplate>
        </telerik:RadWindow.Resources>
        <Grid x:Name="LayoutRoot" Background="White" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200">
            <Grid.RowDefinitions>
                <RowDefinition Height="50" />
                <RowDefinition Height="700" />
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Orientation="Horizontal" Width="200" Height="50">
                <HyperlinkButton x:Name="HypButtonAnnuleren" Content="Annuleren" Margin="5,5,5,5"  Foreground="{StaticResource HypLinkAnnuleren}" Click="HypButtonAnnuleren_Click" />
                <HyperlinkButton x:Name="HypButtonOpslaan" Content="Opslaan" Margin="0,5,0,5"  Foreground="{StaticResource HypLinkOpslaan}" Click="HypButtonOpslaan_Click"/>
            </StackPanel>
            <telerik:RadTreeView Grid.Row="1"
                                 ItemTemplate="{StaticResource Item}"
                                 ItemsSource="{Binding Source={StaticResource treeViewData}}" 
                                 SelectionMode="Extended"
                                 IsLineEnabled="True"
                                 ItemsOptionListType="CheckList"
                                 IsOptionElementsEnabled="True"
                                 IsRootLinesEnabled="True"
                                 Margin="10"
                                 x:Name="RadTreeView1"
                                 IsTriStateMode="True"
                                 />
        </Grid>
    </telerik:RadWindow>

    C# CODE BEHIND (THIS CODE DOES NOT WORK!)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Xml.Serialization;
    using System.Collections.ObjectModel;
    using System.IO;
    using Telerik.Windows.Controls;
    using Jbusiness.Web;
    using System.ServiceModel.DomainServices.Client;
    using System.Windows.Automation;
      
    namespace Jbusiness.Views.Gegevens
    {
        public partial class AdviseurTreeView : RadWindow
        {
      
            private int AdvsID;
      
            public AdviseurTreeView(int advsID)
            {
                InitializeComponent();
      
                this.AdvsID = advsID;
      
                this.RadTreeView1.Loaded += new System.Windows.RoutedEventHandler(RadTreeView1_Loaded);
            }
      
            private void RadTreeView1_Loaded(object sender, System.Windows.RoutedEventArgs e)
            {
                JortnerDomainContext jdc = new JortnerDomainContext();
                LoadOperation<Jbusiness.Web.Adviseur> lop = jdc.Load(jdc.GetAdviseursQuery().Where(ad => ad.AdvsId == this.AdvsID));
                lop.Completed += (s, a) =>
                {
                    string[] superstringArray = (jdc.Adviseurs.ElementAt<Jbusiness.Web.Adviseur>(0).AdvsGebiedenExport as string).Split(new Char[] { ',' });
      
                    int i = 0;
                    int j = 0;
      
                    object[] xni = this.RadTreeView1.Items.ToArray();
      
                    this.RadTreeView1.ExpandAll();
      
                      
                    foreach (RadTreeViewItem rtvi in this.RadTreeView1.ChildrenOfType<RadTreeViewItem>())
                    {
                        i++;
      
                        foreach (string value in superstringArray)
                        {
                            if (((XmlNodeItem)xni[i - 1]).value == value)
                            {
                                rtvi.IsChecked = true;
                            }
                        }
      
                        j = 0;
      
                        object[] xni2 = rtvi.Items.ToArray();
      
                        RadTreeViewItem rtvi2 = this.RadTreeView1.ContainerFromItemRecursive(xni[i - 1]);
      
                        foreach (RadTreeViewItem rtvi3 in rtvi2.ChildrenOfType<RadTreeViewItem>())
                        {
                            j++;
      
                            foreach (string value in superstringArray)
                            {
                                if (((XmlNodeItem)xni2[j - 1]).value == value)
                                {
                                    rtvi3.IsChecked = true;
                                }
                            }
                        }
                    }
                };
            }
      
            private void HypButtonAnnuleren_Click(object sender, RoutedEventArgs e)
            {
      
            }
      
            private void HypButtonOpslaan_Click(object sender, RoutedEventArgs e)
            {
                string superstring = "";
      
      
                foreach (XmlNodeItem xni in this.RadTreeView1.CheckedItems)
                {
                    if (xni.value != null) superstring += xni.value.ToString() + ",";
                }
      
                JortnerDomainContext jdc = new JortnerDomainContext();
                LoadOperation<Jbusiness.Web.Adviseur> lop = jdc.Load(jdc.GetAdviseursQuery().Where(ad => ad.AdvsId == this.AdvsID));
                lop.Completed += (s, a) =>
                {
                    jdc.Adviseurs.ElementAt<Jbusiness.Web.Adviseur>(0).AdvsGebiedenExport = superstring;
      
                    if (jdc.HasChanges)
                    {
                        jdc.SubmitChanges();
                    }
                };
            }
        }
      
        public class XmlNodeItem 
        {
            public XmlNodeItem()
            {
                this.Items = new ObservableCollection<XmlNodeItem>();
            }
      
            [XmlAttribute(AttributeName = "Header")]
            public string Header
            {
                get;
                set;
            }
      
            [XmlAttribute(AttributeName = "value")]
            public string value
            {
                get;
                set;
            }
      
            public ObservableCollection<XmlNodeItem> Items
            {
                get;
                set;
            }
        }
      
        [XmlRoot(ElementName = "Items")]
        public class XmlNodeItemList : ObservableCollection<XmlNodeItem>
        {
            public void AddRange(IEnumerable<XmlNodeItem> range)
            {
                foreach (XmlNodeItem node in range)
                {
                    this.Add(node);
                }
            }
        }
      
        public class RadTreeViewXmlDataSource : XmlNodeItemList
        {
            private string source;
            public string Source
            {
                get
                {
                    return this.source;
                }
                set
                {
                    this.source = value;
                    AddRange(RetrieveData(Application.GetResourceStream(new Uri(value, UriKind.Relative)).Stream));
                }
            }
      
            private XmlNodeItemList RetrieveData(Stream xmlStream)
            {
                XmlSerializer serializer = new XmlSerializer(typeof(XmlNodeItemList));
                StreamReader reader = new StreamReader(xmlStream);
                XmlNodeItemList list = (XmlNodeItemList)serializer.Deserialize(reader);
                return list;
            }
        }
    }

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Items>
      <XmlNodeItem Header="Exportinstellingen">
        <Items>
          <XmlNodeItem Header="Gezin">
            <Items>
              <XmlNodeItem Header="Partners">
                <Items>
                  <XmlNodeItem Header="Persoonlijk" value="10" />
                  <XmlNodeItem Header="Pensioen" value="20" />
                  <XmlNodeItem Header="Werk" value="30" />
                </Items>
              </XmlNodeItem>
              <XmlNodeItem Header="Kinderen" value="40" />
              <XmlNodeItem Header="Woonsituatie" value="50" />
            </Items>
          </XmlNodeItem>
          <XmlNodeItem Header="Adviesgebieden">
            <Items>
              <XmlNodeItem Header="Contracten" value="60" />
              <XmlNodeItem Header="Financieel" value="70" />
              <XmlNodeItem Header="Producten en diensten" value="80" />
              <XmlNodeItem Header="Documenten" value="90" />
            </Items>
          </XmlNodeItem>
          <XmlNodeItem Header="Niet adviesgebieden">
            <Items>
              <XmlNodeItem Header="Contracten" value="100" />
              <XmlNodeItem Header="Financieel" value="110" />
              <XmlNodeItem Header="Producten en diensten" value="120" />
              <XmlNodeItem Header="Documenten" value="130" />
            </Items>
          </XmlNodeItem>
          <XmlNodeItem Header="Budget" value="140" />
          <XmlNodeItem Header="Vermogen" value="150" />
          <XmlNodeItem Header="Documenten">
            <Items>
              <XmlNodeItem Header="Adviesgebieden" value="160" />
              <XmlNodeItem Header="Niet adviesgebieden" value="170" />
              <XmlNodeItem Header="Alle documenten" value="180" />
            </Items>
          </XmlNodeItem>
        </Items>
      </XmlNodeItem>
    </Items>

    See code.

    Many thanks in advance!

    Johan.
     

  2. Answer
    Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 28 Jan 2011 Link to this post

    Hello Johan Van der Galien,

    I examined your projects and I think I detected some problems that could be avoided. First, you are trying to access the RadTreeViewItems in the Loaded event handler of the RadTreeView but they haven't been generated already. The best action you can do is to use the ItemPrepared event of the RadTreeView which fires every time when a RadTreeViewItem is generated. In the ItemPrepared handler You can make your check whether the business object(in your case XMLNodeItem) in the RadTreeViewitem has a proper value. [[ You can also use HashSet<string> instead of string[] array that you have to iterate over ]]. Following this approach, you can avoid a recursive function or a iterations with quadratic complexity. Finally, the value property of the XmlNodeItem class is badly named since "value" is a key word. You can replace it with Value, or something else.
    Please examine the attached project where I have used the described approach and let me know if it satisfies you.

    Kind 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>>
  3. DevCraft banner
  4. Johan Van der Galien
    Johan Van der Galien avatar
    6 posts
    Member since:
    Mar 2010

    Posted 01 Feb 2011 Link to this post

    Dear Petar from Telerik,

    Thank you very much! You made me a better programmer! The Items_Prepared scenario was what we were looking for.

    For your information the idea is to make the TreeView dynamical as such that while in production a system administrator can edit the XML string stored in a database tabel at will without stopping, rebuilding and republishing. We got a control panel only for the administrator role in our silverlight application.

    Kind regards,

    Johan.
Back to Top