2009-11-03 4 views
0

Dans une arborescence WPF, j'essaie de vérifier automatiquement les enfants si le nœud parent est en cours de vérification. J'utilise un modèle de vue pour cela et un objet liable pour les nœuds, mais toutes mes tentatives ont échoué. Voici le code (C# + XAML). Toutes les idées seraient grandement appréciésWPF - Liaison à CheckBox ne fonctionnant pas dans HierarchicalDataTemplate

<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> 

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 
} 

Répondre

0

Oups, les cases à cocher enfants ne sont pas contrôlés parce que je ne déclenchaient pas de leurs biens IsChecked. Je définissais le champ isChecked, qui contourne le setter de propriété et empêche que PropertyChanged soit déclenché.

Questions connexes