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

Checkbox Parent gets unchecked when loading checked children

3 Answers 64 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
tsmithtn
Top achievements
Rank 1
tsmithtn asked on 11 Nov 2011, 06:54 PM

Im trying to hard to get a treeview that has loading on demand enabled with checkboxes. I run into issues if I have a parent node checked and then try to expand it (which triggers a load on demand operation).  If the parent was checked, I build the children and make sure they have the checked property as well. When all is complete, the treeview successfully loads the children, the children are all checked as expected, but the parent node (that was expanded) gets unchecked! WHY?!

<UserControl.Resources>
            <telerik:ContainerBindingCollection x:Key="TreeBindings">
        <telerik:ContainerBinding PropertyName="IsChecked" Binding="{Binding IsChecked, Mode=TwoWay}"/>
    </telerik:ContainerBindingCollection>
      
    <telerik:HierarchicalDataTemplate x:Key="TreeItemTemplate" ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource TreeBindings}">
        <TextBlock Text="{Binding DisplayName}" />
    </telerik:HierarchicalDataTemplate>
</UserControl.Resources>
  
<Grid x:Name="LayoutRoot" Margin="10">
            <telerik:RadTreeView SelectionMode="Single"  Grid.Row="1"
            ItemTemplate="{StaticResource TreeItemTemplate}"
            ItemsSource="{Binding ProcessTreeRoot}" 
            ItemPrepared="processSelectTree_ItemPrepared"               IsLoadOnDemandEnabled="True" LoadOnDemand="processSelectTree_LoadOnDemand"
            ItemsOptionListType="CheckList" 
            IsOptionElementsEnabled="True" 
            IsExpandOnSingleClickEnabled="False" 
            telerik:ContainerBinding.ContainerBindings="{StaticResource TreeBindings}"
            Margin="10" x:Name="processSelectTree" IsTriStateMode="True">
          
    </telerik:RadTreeView>
</Grid>

My relavant code behind :

private void processSelectTree_LoadOnDemand(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
    RadTreeViewItem treeitem = e.OriginalSource as RadTreeViewItem;
    (DataContext as DocumentAssignmentByProcessViewModel).LoadChildrenOnDemandCommand.Execute(treeitem.Item as PlantConfigTreeItem);
}
private void processSelectTree_ItemPrepared(object sender, Telerik.Windows.Controls.RadTreeViewItemPreparedEventArgs e)
{
    RadTreeViewItem treeitem = (RadTreeViewItem)e.PreparedItem;
    treeitem.IsLoadOnDemandEnabled = (treeitem.Item as PlantConfigTreeItem).HasChildren;
}


My View Model related code (command code triggered on load demand)

protected void LoadChildrenOnDemand(PlantConfigTreeItem objTreeItem)
{
    if (objTreeItem is LineTreeItem)
    {
    //  string userClockNum = (HandbookMode == enHandbookMode.ALL) ? "" : ECAPApplicationState.Instance.LoggedInAssociate.ClockNumber;
        prodContext.Load(prodContext.GetPositionsQuery("",
            ECAPApplicationState.Instance.CurrentDivisionPlantConfigId,
            objTreeItem.Id),
            io =>
            {
                ObservableCollection<PlantConfigTreeItem> positionList = new ObservableCollection<PlantConfigTreeItem>();
                foreach (Position pl in io.Entities ) 
                    positionList.Add(new PositionTreeItem { Id = pl.Id, DisplayName = pl.PositionTitle, HasChildren = true, IsChecked = objTreeItem.IsChecked });
                AddRange( objTreeItem.Children, positionList);
            },
            null
        );
    }
    else if (objTreeItem is PositionTreeItem)
    {
        //  string userClockNum = (HandbookMode == enHandbookMode.ALL) ? "" : ECAPApplicationState.Instance.LoggedInAssociate.ClockNumber;
        prodContext.Load(prodContext.GetAllProcessQuery("",
            ECAPApplicationState.Instance.CurrentDivisionPlantConfigId,
            objTreeItem.Id),
            io =>
            {
                ObservableCollection<PlantConfigTreeItem> positionList = new ObservableCollection<PlantConfigTreeItem>();
                foreach (Process pl in io.Entities)
                    positionList.Add(new ProcessTreeItem { Id = pl.Id, DisplayName = pl.Name, HasChildren = false, IsChecked = objTreeItem.IsChecked });
                AddRange(objTreeItem.Children, positionList);
            },
            null
        );
    }
}






3 Answers, 1 is accepted

Sort by
0
Tina Stancheva
Telerik team
answered on 16 Nov 2011, 02:07 PM
Hi Tsmithtn,

Unfortunately this is a known issue - it is logged in our PITS here. As a workaround you can try to reset the parent item check state in the processSelectTree_LoadOnDemand event handler using a Dispatcher:
private void processSelectTree_LoadOnDemand(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
    RadTreeViewItem treeitem = e.OriginalSource as RadTreeViewItem;
    (DataContext as DocumentAssignmentByProcessViewModel).LoadChildrenOnDemandCommand.Execute(treeitem.Item as PlantConfigTreeItem);
 
    Dispatcher.BeginInvoke(new Action(() => { treeitem.IsChecked = true; }));
}

Give this approach a try and let us know if it helps.

Kind regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
tsmithtn
Top achievements
Rank 1
answered on 16 Nov 2011, 02:17 PM
I had tried that approach to no avail. However, I did figure out order of events and was able to add code to the code behind to get it to work. Hopefully this will help someone else out as i saw this question posted several times without concrete solution.

I changed my bindings to the CheckState property (as opposed to isChecked property). Final XAML below:
    <UserControl.Resources>
        <!-- Page Converters -->
        <converters:BooleanToToggleStateConverter x:Key="Bool2ToggleConverter" />
          
        <telerik:ContainerBindingCollection x:Key="TreeBindings">
            <telerik:ContainerBinding  PropertyName="CheckState" Binding="{Binding IsChecked, Mode=TwoWay, Converter={StaticResource Bool2ToggleConverter}}" />
            <telerik:ContainerBinding PropertyName="IsExpanded" Binding="{Binding IsExpanded, Mode=TwoWay}" />
        </telerik:ContainerBindingCollection>
          
        <telerik:HierarchicalDataTemplate x:Key="TreeItemTemplate" ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource TreeBindings}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding DisplayName}" />
            </StackPanel>
        </telerik:HierarchicalDataTemplate>
    </UserControl.Resources>
      
    <Grid x:Name="LayoutRoot" Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
  
              
        <telerik:RadTreeView SelectionMode="Single"  Grid.Row="1"
                ItemTemplate="{StaticResource TreeItemTemplate}"
                ItemsSource="{Binding ProcessTreeRoot}" 
                ItemPrepared="processSelectTree_ItemPrepared"
                IsLoadOnDemandEnabled="True" LoadOnDemand="processSelectTree_LoadOnDemand"
                ItemsOptionListType="CheckList"
                IsOptionElementsEnabled="True" 
                PreviewUnchecked="processSelectTree_PreviewUnchecked"
                IsExpandOnSingleClickEnabled="True" 
                telerik:ContainerBinding.ContainerBindings="{StaticResource TreeBindings}"
                Checked="processSelectTree_Checked" Unchecked="processSelectTree_Checked"
                Margin="0" 
                x:Name="processSelectTree"
                IsTriStateMode="True" />
  
    </Grid>
      
</UserControl>

The magic happens in my code behind. I set a flag to detect when a node is being expanded and not yet loaded. Since this event happens before the unwanted Unchecked event, I am able to use the PreviewUnchecked event to see if Im in this unwanted state. If I am, I simply throw that event away:

{
    private bool bExpandingCheckedUnloadedItem_TelerikHack = false;
    public DocumentAssignmentByProcess()
    {
        InitializeComponent();
    }
    private void processSelectTree_LoadOnDemand(object sender, Telerik.Windows.RadRoutedEventArgs e)
    {
        RadTreeViewItem treeitem = e.OriginalSource as RadTreeViewItem;
        (DataContext as DocumentAssignmentByProcessViewModel).LoadChildrenOnDemandCommand.Execute(treeitem.Item as PlantConfigTreeItem);
        // telerik tree hack. apparently if a node is checked (and not yet loaded), it will get unchecked when expanded
        if (treeitem.CheckState == System.Windows.Automation.ToggleState.On)
        {
            treeitem.IsChecked = true;
            bExpandingCheckedUnloadedItem_TelerikHack = true;
        }
    }
    private void processSelectTree_ItemPrepared(object sender, Telerik.Windows.Controls.RadTreeViewItemPreparedEventArgs e)
    {
        RadTreeViewItem treeitem = (RadTreeViewItem)e.PreparedItem;
        treeitem.IsLoadOnDemandEnabled = (treeitem.Item as PlantConfigTreeItem).HasChildren;
    }
    private void processSelectTree_PreviewUnchecked(object sender, Telerik.Windows.RadRoutedEventArgs e)
    {
        // more of the hack.. after the tree node is expanded, the tree control for some reason unselects the parent node
        // this code checks for situatio where node was originally checked (indicated by bExpandingCheckedUnloadedItem) 
        // and will check it and cancel uncheck event
        if (bExpandingCheckedUnloadedItem_TelerikHack)
        {
            bExpandingCheckedUnloadedItem_TelerikHack = false;
            e.Handled = true;
            RadTreeViewItem treeitem = e.OriginalSource as RadTreeViewItem;
            treeitem.IsSelected = true;
        }
    }






0
Tina Stancheva
Telerik team
answered on 16 Nov 2011, 02:27 PM
Hello Tsmithtn,

Thank you for sharing your solution. I am sure it will be highly appreciated by the community.

Kind regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
TreeView
Asked by
tsmithtn
Top achievements
Rank 1
Answers by
Tina Stancheva
Telerik team
tsmithtn
Top achievements
Rank 1
Share this question
or