Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Binding WPF-绑定到复选框在HierarchycalDataTemplate中不起作用_Binding_Checkbox_Hierarchicaldatatemplate - Fatal编程技术网

Binding WPF-绑定到复选框在HierarchycalDataTemplate中不起作用

Binding WPF-绑定到复选框在HierarchycalDataTemplate中不起作用,binding,checkbox,hierarchicaldatatemplate,Binding,Checkbox,Hierarchicaldatatemplate,在WPF树视图中,如果正在检查父节点,我将尝试自动检查子节点。我正在使用一个视图模型和一个可绑定的对象,但是我所有的尝试都失败了。下面是代码(C#+XAML)。任何想法都将不胜感激 <Window x:Class="TestCheckBoxBinding.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/

在WPF树视图中,如果正在检查父节点,我将尝试自动检查子节点。我正在使用一个视图模型和一个可绑定的对象,但是我所有的尝试都失败了。下面是代码(C#+XAML)。任何想法都将不胜感激

<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>
    <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}"></CheckBox>
            <Label Content="{Binding Name}"></Label>
        </StackPanel>
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView ItemsSource="{Binding Categories, Mode=OneTime}"></TreeView>
</Grid>

公共类TestsViewModel
{
公共静态void PopulateList(TestsViewModel vm)
{
TestCategory cat1=newTestCategory(){Id=1,Name=“First category”};
testt1=newtest(){Name=“Test1”};
testt2=newtest(){Name=“Test2”};
Test t3=new Test(){Name=“Test3”};
t1.AddChild(t2);
t1.AddChild(t3);
测试t4=新测试(){Name=“Test4”};
cat1.AddTest(t1);
cat1.AddTest(t4);
vm.AddTestCategory(cat1);
TestCategory cat2=newTestCategory(){Id=2,Name=“Second category”};
Test t5=new Test(){Name=“Test1”};
测试t6=新测试(){Name=“Test2”};
Test t7=new Test(){Name=“Test3”};
t6.AddChild(t7);
Test t8=new Test(){Name=“Test4”};
cat2.AddTest(t5);
cat2.AddTest(t6);
cat2.AddTest(t8);
vm.AddTestCategory(cat2);
}
私有只读IEnumerable categories=新列表();
公共IEnumerable类别{get{return Categories;}}
公共void AddTestCategory(TestCategory TestCategory)
{
添加(testCategory);
}
}
公共类TestCategory
{
公共int Id{get;set;}
公共字符串名称{get;set;}
私有只读IEnumerable测试=新列表();
公共IEnumerable测试{get{return Tests;}}
公共测试(测试t)
{
((IList)测试)。添加(t);
}
}
公共类测试:INotifyPropertyChanged
{
私有字符串名称;
公共字符串名
{
设置
{
如果(名称!=值)
{
名称=值;
本协议项下的不动产变更(“名称”);
}
}
获取{返回名称;}
}
公共bool?isChecked=false;
公共场所被检查了
{
获取{return isChecked;}
设置
{
如果(已检查!=值)
{
isChecked=值;
if(children.Count()>0)
{
foreach(儿童var测试)
{
test.isChecked=值;
test.Name+=”;
}
}
本条关于财产的变更(“已检查”);
}
}
}
公共void AddChild(测试)
{
((IList)儿童)。添加(测试);
}
private readonly IEnumerable children=新列表();
可数儿童的公共教育
{
获取{返回子项;}
}
#区域INotifyProperty更改成员
//创建OnPropertyChanged方法以引发事件
受保护的void OnPropertyChanged(字符串propName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(此,新PropertyChangedEventArgs(propName));
}
}
公共事件属性更改事件处理程序属性更改;
#端区
}

由于我没有设置子复选框的IsChecked属性,因此未选中子复选框。我正在设置isChecked字段,它绕过属性设置程序并防止引发PropertyChanged

public class TestsViewModel
{
    public static void PopulateList(TestsViewModel vm)
    {
        TestCategory cat1 = new TestCategory() { Id = 1, Name = "First category" };
        Test t1 = new Test() { Name = "Test1" };
        Test t2 = new Test() { Name = "Test2" };
        Test t3 = new Test() { Name = "Test3" };
        t1.AddChild(t2);
        t1.AddChild(t3);
        Test t4 = new Test() { Name = "Test4" };
        cat1.AddTest(t1);
        cat1.AddTest(t4);
        vm.AddTestCategory(cat1);
        TestCategory cat2 = new TestCategory() { Id = 2, Name = "Second category" };
        Test t5 = new Test() { Name = "Test1" };
        Test t6 = new Test() { Name = "Test2" };
        Test t7 = new Test() { Name = "Test3" };
        t6.AddChild(t7);
        Test t8 = new Test() { Name = "Test4" };
        cat2.AddTest(t5);
        cat2.AddTest(t6);
        cat2.AddTest(t8);
        vm.AddTestCategory(cat2);
    }
    private readonly IEnumerable<TestCategory> categories = new List<TestCategory>();
    public IEnumerable<TestCategory> Categories { get { return categories; } }
    public void AddTestCategory(TestCategory testCategory)
    {
        ((IList<TestCategory>)categories).Add(testCategory);
    }
}

public class TestCategory
{
    public int Id { get; set; }
    public string Name { get; set; }
    private readonly IEnumerable<Test> tests = new List<Test>();
    public IEnumerable<Test> Tests { get { return tests; } }
    public void AddTest(Test t)
    {
        ((IList<Test>)tests).Add(t);
    }
}

public class Test : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        set
        {
            if (name != value)
            {
                name = value;
                this.OnPropertyChanged("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 += ".";
                    }
                }
                this.OnPropertyChanged("IsChecked");
            }
        }
    }

    public void AddChild(Test test)
    {
        ((IList<Test>)children).Add(test);
    }

    private readonly IEnumerable<Test> children = new List<Test>();
    public IEnumerable<Test> Children
    {
        get { return children; }
    }

    #region INotifyPropertyChanged Members

    // Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string propName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}