Microsoft Developer Network > Domovská stránka fór > Windows Presentation Foundation (WPF) > Binding CheckBoxes in a Hierachical datatemplate doesn't seem to work properly
Odeslat dotazOdeslat dotaz
 

OdpovědětBinding CheckBoxes in a Hierachical datatemplate doesn't seem to work properly

  • 4. listopadu 2009 16:07Dan Mincu Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Can anyone explain me why the children checkboxes are not updated by the change in the parent checkbox in the following example?
    And second question: How do I get back the the datacontext on a CheckBox Click event?
    Thanks in advance,
    Dan

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;

    namespace TestCheckBoxBinding
    {
        public class TestsViewModel
        {
            public static TestsViewModel ExampleDataContext
            {
                get
                {
                    TestsViewModel vm = new TestsViewModel();
                    TestCategory cat1 = new TestCategory() {Name = "First category"};
                    Test t1 = new Test() {Name = "Test1"};
                    Test t2 = new Test() {Name = "Test2"};
                    Test t3 = new Test() {Name = "Test3"};
                    t1.Children.Add(t2);
                    t1.Children.Add(t3);
                    Test t4 = new Test() {Name = "Test4"};
                    cat1.Tests.Add(t1);
                    cat1.Tests.Add(t4);
                    vm.Categories.Add(cat1);
                    return vm;
                }
            }

            private readonly IList<TestCategory> categories = new List<TestCategory>();
            public IList<TestCategory> Categories { get { return categories; } }
        }

        public class TestCategory
        {
            public string Name { get; set; }
            private readonly IList<Test> tests = new List<Test>();
            public IList<Test> Tests { get { return tests; } }
        }

        public class Test : INotifyPropertyChanged
        {
            private string name;
            public string Name
            {
                set
                {
                    if (name != value)
                    {
                        name = value;
                        if (PropertyChanged != null)
                            PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                    }
                }
                get { return name; }
            }

            public bool? isChecked = false;
            public bool? IsChecked
            {
                get { return isChecked; }
                set
                {
                    if (isChecked != value)
                    {
                        isChecked = value;
                        if (children.Count() > 0)
                        {
                            foreach (var test in children)
                            {
                                test.isChecked = value;
                                test.Name += ".";
                            }
                        }
                        if (PropertyChanged != null)
                            PropertyChanged(this,new PropertyChangedEventArgs("IsChecked"));
                    }
                }
            }

            private readonly IList<Test> children = new List<Test>();

            public IList<Test> Children
            {
                get { return children; }
            }

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            #endregion
        }

    <Window x:Class="TestCheckBoxBinding.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestCheckBoxBinding"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <local:TestsViewModel x:Key="dataContext"></local:TestsViewModel>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="True"/>
            </Style>
            <HierarchicalDataTemplate DataType="{x:Type local:TestCategory}" ItemsSource="{Binding Tests, Mode=OneTime}">
                <Label Content="{Binding Name}"></Label>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type local:Test}" ItemsSource="{Binding Children, Mode=OneTime}">
                <StackPanel Orientation="Horizontal">
                    <CheckBox VerticalAlignment="Center"  IsChecked="{Binding IsChecked, Mode=TwoWay}" Focusable="False" Click="CheckBox_Click"></CheckBox>
                    <Label Content="{Binding Name}"></Label>
                </StackPanel>
            </HierarchicalDataTemplate>
        </Window.Resources>
        <Grid DataContext="{Binding Source={StaticResource dataContext}, Path=ExampleDataContext}" >
            <TreeView ItemsSource="{Binding Categories, Mode=OneTime}"></TreeView>
        </Grid>
    </Window>

Odpovědi

  • 4. listopadu 2009 16:42Dan Mincu Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Oups,  child checkboxes are not being checked because I wasn't setting their IsChecked property. I was setting the isChecked field, which bypasses the property setter and prevents PropertyChanged from being raised.
    • Označen jako odpověďDan Mincu 4. listopadu 2009 16:44
    •  

Všechny reakce

  • 4. listopadu 2009 16:42Dan Mincu Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Oups,  child checkboxes are not being checked because I wasn't setting their IsChecked property. I was setting the isChecked field, which bypasses the property setter and prevents PropertyChanged from being raised.
    • Označen jako odpověďDan Mincu 4. listopadu 2009 16:44
    •