powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Binding Selected TreeNode
6 сообщений из 6, страница 1 из 1
Binding Selected TreeNode
    #38844617
fritz321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
весь вечер голову ломаю - не могу придмумать как забиндить выделенный сегмент TreeView переменной Mvvm

весь TreeView тут
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
<TreeView ItemsSource="{Binding Subunits}">
                    <!-- Шаблон подразделения -->
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Positions}">
                            <TextBlock Text="{Binding SubunitName}"/>
                            <!-- Шаблон должности -->
                            <HierarchicalDataTemplate.ItemTemplate>
                                <HierarchicalDataTemplate ItemsSource="{Binding Employees}" DataType="{x:Type local:Employee}">
                                    <TextBlock Text="{Binding PositionName}"/>
                                    <!-- Шаблон сотрудника -->
                                    <HierarchicalDataTemplate.ItemTemplate>
                                        <DataTemplate>
                                            <StackPanel Orientation="Horizontal">                                                
                                                <TextBlock Text="{Binding FirstName}" Margin="0,0,5,0" MouseDown="qwe"/>
                                                <TextBlock Text="{Binding FirstName}" Margin="0,0,5,0"/>
                                                <TextBlock Text="{Binding Patronymic}" Margin="0,0,5,0"/>
                                            </StackPanel>
                                        </DataTemplate>
                                    </HierarchicalDataTemplate.ItemTemplate>
                                    
                                </HierarchicalDataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>



плюс сложность в том что каждый дочерний узел, экземпляр другого класса, чем родительский, но я думаю не проблема.
Просто не могу найти решение о том как на клик забиндить переменную HierarchicalDataTemplate
...
Рейтинг: 0 / 0
Binding Selected TreeNode
    #38844723
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а) для начала в модели представления нужно создать базовый класс для элемента иерархического списка.
он может наследоваться от базового класса модели представления или как то еще, дело ваше.
Лично я создаю примерно такой класс:

вот пример такого класса взятый из проекта:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
    public sealed class LoadingTreeItem : BaseTreeItem
    {
        public override string DisplayName
        {
            get { return "Loading..."; }
        }
    }

    public abstract class BaseTreeItem : INotifyPropertyChanged
    {
        public static ObservableCollection<BaseTreeItem> LoadingItems { set; get; }

        static BaseTreeItem()
        {
            LoadingItems = new ObservableCollection<BaseTreeItem> {new LoadingTreeItem()};
        }

        private bool _isExpanded;
        private ObservableCollection<BaseTreeItem> _children;
        public virtual string DisplayName { set; get; }

        public ObservableCollection<BaseTreeItem> Children
        {
            set
            {
                if (Equals(value, _children)) return;
                _children = value;
                OnPropertyChanged();
            }
            get
            {
                ObservableCollection<BaseTreeItem> result;
                if (IsLoaded && HasItems) return _children;
                if (!IsLoaded && HasItems) return LoadingItems;
                return null;
            }
        }

        public BaseTreeItem Parent { set; get; }

        public bool HasItems
        {
            set
            {
                if (value.Equals(_hasItems)) return;
                _hasItems = value;
                OnPropertyChanged();
            }
            get { return _hasItems; }
        }

        public virtual bool IsLoaded { set; get; }
        public virtual bool IsLoading { set; get; }
        public Func<BaseTreeItem, IEnumerable<BaseTreeItem>> LoadChildrenFunc { set; get; }
        public bool IsSelected { set; get; }

        public bool IsExpanded
        {
            set
            {
                if (!CanExpand) return;
                if (value.Equals(_isExpanded)) return;
                _isExpanded = value;
                if (_isExpanded) LoadChildren();
                OnPropertyChanged();
            }
            get { return _isExpanded; }
        }

        private Task<IEnumerable<BaseTreeItem>> GetChildren()
        {
            var factory = new TaskFactory();
            return factory.StartNew(() => LoadChildrenFunc(this));
        }

        public bool CanExpand { get { return LoadChildrenFunc != null; } }

        private bool _hasItems;

        private async void LoadChildren()
        {
            if (!CanExpand) return;

            IsLoading = true;
            var result = await GetChildren();
            IsLoading = false;
            IsLoaded = true;
            Children = new ObservableCollection<BaseTreeItem>(result);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }


у данного базового класса есть свойство IsSelected, он примет значение True. В качество метода для загрузки элементов используется делегат, который вызывается асинхронно и загружает элементы дерева. Это достаточно топорный пример, я просто дома и что нашел, то и скинул.
Само свойство определяющее выделение элемента находится в элемента TreeViewItem, в котором размещается шаблон данных. TreeView Автоматически создает данный элемент и размещает его в своей панели, а внутри размещает ContentPresenter для шаблона данный. (всё это можно увидеть в визуальном дереве WPF приложения с помощью сторонних утилит или внутр. инструментами). TreeViewItem имеет зависимое свойство IsSelected и именно к нему нужно биндить свойства в модели преставления.
Вот пример:
Код: xml
1.
2.
3.
4.
5.
        
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
        </Style>


обязательно указываем режим связывания TwoWay, так как по умолчанию они OneWay.
Вот собственно и всё. Теперь выделенные элементы дерева будут имеет свойство IsSelected, нужно их только найти и использовать. ) Но вообще, в WPF это вообще не нужно в большинстве случаев. Так как при использовании маршрутизирующих и обычных команд, ты можешь передать в виде параметра выделенный элемент дерева и не париться с его поиском вообще. Этот вариант как по мне будет более правильный.
...
Рейтинг: 0 / 0
Binding Selected TreeNode
    #38844736
fritz321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторты можешь передать в виде параметра выделенный элемент дерева и не париться с его поиском вообще. Этот вариант как по мне будет более правильный.
можно об этом поподробней?
...
Рейтинг: 0 / 0
Binding Selected TreeNode
    #38844769
fritz321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtes,

нашел хорошее решение вот тут
но оно помогло только от части.

Там описывается расширенный класс TreeView которому добавляется свойство SelectedItem
Вопрос остался в создании такого класса для HierarchicalDataTemplate потому что у него такого свойства нет
...
Рейтинг: 0 / 0
Binding Selected TreeNode
    #38844933
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fritz321,

напиши на скайп и я вышлю тебе пример проекта roman_meites.
AttachedProperty для такой простой задачи вообще бесмысленен.
Всё это можно сделать прямо в модели представления.
способ через AttachedProperty основан на рекурсивном поиске по визуальному дереву (скорее всего). Тоже вариант, но имхо слишком громоздкий.
...
Рейтинг: 0 / 0
Binding Selected TreeNode
    #38845011
fritz321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtes,

почта моя kolenchits86@gmail.com
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Binding Selected TreeNode
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]