WPF TreeView DataBinding дерево не обновляется динамически при обновлении свойств элементов источника

Статус: Offline
Реєстрація: 30.03.2007
Повідом.: 1286
WPF TreeView DataBinding дерево не обновляется динамически при обновлении свойств элементов источника

Есть элемент TreeView. В XAML его заголовок выглядит так:

Код:
<TreeView Name="tree" Grid.Row="2" ItemsSource="{Binding cTask, Path=Tasks, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItemChanged="tree_SelectedItemChanged">

привязанный к коллекции Tasks (ObservableCollection<Task> Tasks) объекта cTask. Режим binding-а я указал TwoWay.

Если я добавляю объекты Task в коллекцию:

Код:
cTask.Add(new Task());

в TreeView элементы тоже добавляются, т.к. объект привязки - коллекция Tasks изменяется. Тут все правильно.

Но! Я хочу заменять шаблон отображения текущего выбранно элемента в TreeView. Все элементы представлены в TreeView одним текстовым полем объекта Task, а выбранный элемент должен состоять из этого поля + некоторых других элементов, вобщем к нему должен применяться другой шаблон. Задачу выбора нужного шаблона я решил с помощью селекторов шаблонов

Код:
	    <TreeView.ItemTemplateSelector>
                <local:TaskTemplateSelector
                    DefaultTemplate="{StaticResource DefaultTemplate}"
                    HighlightTemplate="{StaticResource HighlightTemplate}" 
                    PropertyToEvaluate="IsSelected" 
                    PropertyValueToHighlight="True">
                </local:TaskTemplateSelector>
            </TreeView.ItemTemplateSelector>


который для элемента Task со значением свйоства IsSelected равным true выбирает специальный шаблон HighlightTemplate, а все остальные отображаются при помощи шаблона DefaultTemplate.

В обработчик события SelectedItemChanged (которое возникает при изменении выбранного элемента) дерева TreeView я написал следующий код:

Код:
if (tree.SelectedItem != null)
{
	sTask = (Task)tree.SelectedItem;
	sTask.IsSelected = true;
}


Надеясь что при изменении свойства конкретного объекта Task из коллекции источника TreeView применит шаблон HighlightTemplate для его отображения, но этого не происходит. Выходит что ItemsColtrol-ы динамически реагируют только на изменение самого объекта привязки и не реагируют на изменение отдельных свойств объекта привязки :( Помогите решить проблему, если кто-то понял о чем я.

В случае если в код добавить

tree.Items.Refresh();

или

переподключить ItemsSource дереву:

tree.ItemsSource = null;
tree.ItemsSource = cTask.Tasks;

то дерево будет перерисовано и шаблон отображения для элемента поменяется, но тогда фокус уйдет с выбранного элемента и все ветки дерева свернуться. Мне естественно нужно оставлять элемент выбранным, т.к. именно для него должен будет отображаться спецовый шаблон.
 
код:

Код:
if (tree.SelectedItem != null)
{
	sTask = (Task)tree.SelectedItem;
	sTask.IsSelected = true;
}

Помогите решить проблему, если кто-то понял о чем я.

если я правильно понял, ты изменяешь свойство своего объекта, но биндинг не видит это изменение, верно? В таком случае скажи - твой объект Task реализует интерфейс INotifyPropertyChanged? Если реализует, вызывает ли он PropertyChanged в сеттере свойства IsSelected?
 
если я правильно понял, ты изменяешь свойство своего объекта, но биндинг не видит это изменение, верно?
Абсолютно верно

В таком случае скажи - твой объект Task реализует интерфейс INotifyPropertyChanged? Если реализует, вызывает ли он PropertyChanged в сеттере свойства IsSelected?
Спасибо за совет, сейчас попробую



Реализовал:

Код:
public class Task : INotifyPropertyChanged
{
...
bool isSelected;
...
 
public event PropertyChangedEventHandler PropertyChanged;
 
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
 
        public bool IsSelected
        {
            set
            {
                isSelected = value;
                NotifyPropertyChanged("IsSelected");
            }
            get { return isSelected; }
        }
....

Все равно, при изменении свойства:

Код:
private void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            sTask = (Task)tree.SelectedItem;
            sTask.IsSelected = true;
        }

ничего не происходит с отображением в TreeView. Вот засада! :confused:

Вот XAML treeview-а:
Код:
<TreeView Name="tree" Grid.Row="2" ItemsSource="{Binding cTask, Path=Tasks, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItemChanged="tree_SelectedItemChanged" KeyDown="tree_KeyDown">
            <TreeView.ItemTemplateSelector>
                <local:TaskTemplateSelector
                    DefaultTemplate="{StaticResource DefaultTemplate}"
                    HighlightTemplate="{StaticResource HighlightTemplate}" 
                    PropertyToEvaluate="IsSelected" 
                    PropertyValueToHighlight="True">
                </local:TaskTemplateSelector>
            </TreeView.ItemTemplateSelector>
        </TreeView>

Хочу чтобы включался шаблон HighlightTemplate для выбранной Task. Он то включается для всех Task, у которых IsSelected = true, но именно динамически, при выборе почему-то не хочет, хотя вроде бы все правильно делаю, в обработчике tree_SelectedItemChanged меняю IsSelected выбранного Task-а на true. Может быть что-то еще упустил? Не могу сообразить :eek:



аааа! Я это сделал! :) И без всяких селекторов:

Код:
             <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="HeaderTemplate" Value="{StaticResource DefaultTemplate}" />
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="HeaderTemplate" Value="{StaticResource HighlightTemplate}"></Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
 
Останнє редагування:
Назад
Зверху Знизу