Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > связать свойство isChecked у чекбоксов


Автор: hexzo 31.5.2011, 11:26
http://s1.ipicture.ru/uploads/20110531/ziIWWVDR.bmp

Иерархический список чекбоксов рисуется вот таким шаблоном.

Код

   <TreeView Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="treeView1" VerticalAlignment="Top" Width="210" ItemsSource="{Binding Source={x:Static Member=src:element.get_hierarchy}}">
      <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type src:element}" ItemsSource="{Binding Path=childs}">
          <CheckBox Content="{Binding Path=name}"/>          
        </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>
    </TreeView>


Как бы забиндить свойства IsChecked у флажков со всеми флажками чекбоксов которые лежат ниже по иерархии. То есть что бы одним щелчком можно было выделить целую ветвь.

P.S. движок картинку вставлять не хочет.

Автор: SergeyLoginov 31.5.2011, 13:04
Я так понимаю, что надо привязываться к булевскому свойству контекста данных (узел дерева). Это свойство надо реализовать. И при изменении его изменять значение этого же свойства у дочерних элементов. Это судя по всему стоит делать в коде.

Автор: hexzo 31.5.2011, 14:27
SergeyLoginov
Цитата
И при изменении его изменять значение этого же свойства у дочерних элементов.

Но чекбокс кажется ничего не знает ни о каких иерархиях.

В TreeViewItem есть свойство Header, которое указывает на элемент выше по иерархии. А вот как к нему, в моём примере с шаблоном, событие привязать?
 smile 

Автор: SergeyLoginov 1.6.2011, 09:59
Ну как же. 
Код

<CheckBox Content="{Binding Path=name}"/>

Здесь же осуществляется привязка к свойству name. Это свойство контекста данных - узла дерева. Типа такого:
Код

public class TreeNode : System.ComponentModel.INotifyPropertyChanged
    {
        private System.Collections.ObjectModel.ObservableCollection<TreeNode> children = new System.Collections.ObjectModel.ObservableCollection<TreeNode>();
        private string name;
        /// <summary>
        /// Дочерние узлы
        /// </summary>
        public System.Collections.ObjectModel.ObservableCollection<TreeNode> Children
        {
            get { return children; }             
        }      
        /// <summary>
        /// Имя узла
        /// </summary>
        public string Name
        {
            get { return name; }
            set 
            { 
                name = value;
                OnPropertyChanged("Name");
            }
        }
        private bool _checked = false;

        /// <summary>
        /// Помечен ли узел галочкой комбобокса
        /// </summary>
        public bool Checked
        {
            get { return _checked; }
            set 
            {
                _checked = value;
                foreach (var child in Children)
                {
                    child.Checked = _checked;
                }
                OnPropertyChanged("Checked");
            }
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="name"></param>
        public TreeNode(string name)
        {
            Name = name;
        }

        #region INotifyPropertyChanged Members
        /// <summary>
        /// Событие на изменение свойства
        /// </summary>
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Уведомление об изменении свойства (все объекты представления привязаные к этому свойству автоматически обновят себя)
        /// </summary>
        /// <param name="propertyName">Имя свойства принимающего новое значение</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }


Только Name с большой буквы. А чтобы было как Вы хотите, надо чтобы xaml выглядел примерно так:
Код

<TreeView Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="treeView1" VerticalAlignment="Top" Width="210" ItemsSource="{Binding MyNodes}}">
      <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type src:TreeNode}" ItemsSource="{Binding Path=Children}">
          <CheckBox Content="{Binding Path=Name}" IsChecked={Binding Checked}/>          
        </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>
    </TreeView>


MyNodes - список узлов первого уровня дерева. 
P.S. Код не проверял, могут быть неточности. Но смысл такой.

Автор: hexzo 2.6.2011, 07:46
Аааааа, ясно.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)