Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
WPF

Поиск дочернего элемента по имени в DependencyObject

01.05.2019, 06:05. Показов 5999. Ответов 27

Студворк — интернет-сервис помощи студентам
Разобрался как добавить вкладку TabItem в TabControl с помощью XAML разметки, а не создавая потом в ней все элементы кодом.

C#
1
2
DataTemplate contentCatalogFundTemplate = (DataTemplate)FindResource("FundCatalog");
tab_item.Content  = contentCatalogFundTemplate.LoadContent();
LoadContent() возвращает DependencyObject.
Можно получать доступ к нужным полям, например так

C#
1
2
3
TabItem tab_item = (TabItem)openDocuments.Items[openDocuments.SelectedIndex];
StackPanel searchMenu = (StackPanel)((StackPanel)tab_item.Content).Children[0];
string keyPhrase = ((TextBox)searchMenu.Children[5]).Text;
Но так логика слишком зависима от представления в интерфейсе.

TabItem и другие элементы наследует от DependencyObject. Возможно написать функцию принимающую DependencyObject корневого элемента, имя элемента в разметки и возвращающую искомый элемент, который может находится в глубине дерева элементов, а не быть первым потомком.

Добавлено через 9 минут
Ещё почему DependencyObject?

Иногда и в загруженном шаблоне надо пометь значение некоторого поля перед тем как его назначить элементу.

Добавлено через 4 часа 1 минуту
Работает это

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        private DependencyObject FindElement(DependencyObject root, string name)
        {
            if (FindElementhelper(root, name, out DependencyObject found)) return found;
            else throw new NotImplementedException(); 
        }
 
        private bool FindElementHelper(DependencyObject root, string name, out DependencyObject found)
        {
            found = root;
            if (root is FrameworkElement && ((FrameworkElement)root).Name == name) return true;
            if (root is Panel)
            {
                foreach (UIElement children in ((Panel)root).Children)
                {
                    if (FindElementhelper(children, name, out found)) return true;
                }
                return false;
            }
            return false;
        }
Хотя это не полный обход. Не учитываются ContentControl и ContentElement. Но мне этого достаточно для текущих шаблонов. (Тем более, что при поиске например в TabControl встаёт ещё вопрос, а искать во всех вкладках или в выбранной).
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.05.2019, 06:05
Ответы с готовыми решениями:

Simple_html_dom поиск дочернего элемента
find('div ') этот код находит DIV с классом rate-shop, мне надо найти элементы h3 - дочерние для этого дива. Пробывал и так и эдак -...

Поиск последнего дочернего элемента и добавление следующего в xml-документе
По наработкам: для всех элементов item вставить schema, если последний из дочерних элементов item-a = title. Xml вида: <?xml...

XML: по имени элемента (тега) и/или имени атрибута у элемента (у тега) выдать соответствующее значение
Есть некий XML файл. . <?xml version="1.0" encoding="windows-1251"?> <ТКвит xmlns="urn:cbr-ru:tk:v1.1" ...

27
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
09.05.2019, 07:41  [ТС]
Студворк — интернет-сервис помощи студентам
При открытии каталога отобразил коллекцию фондов возвращённую из БД
C#
1
2
3
4
5
6
7
8
9
10
11
if (typeCatalog == TypeCatalog.Funds)
{
                Tabs.Add(new FundsViewModel()
                {
                    Title = "Фонды",
                    
                    Items = FundsViewModel.ListFundToCollectionFundViewModel(Fund.FindFund(0,"",null,null))
 
                });
                SelectedIndex = Tabs.Count - 1;
}
В FundsViewModel добавил функцию подготавливающую коллекцию фондов
C#
1
2
3
4
5
6
7
8
9
static internal ObservableCollection<FundViewModel> ListFundToCollectionFundViewModel(List<Fund> funds)
{
            ObservableCollection<FundViewModel> collectionFundViewModel = new ObservableCollection<FundViewModel>();
            foreach (Fund fund in funds)
            {
                collectionFundViewModel.Add(new FundViewModel().FundToFundViewModel(fund));
            }
            return collectionFundViewModel;
}
Часть логики, что показывать FundsViewModel находится в элементах управления

C#
1
2
3
4
5
6
7
8
9
10
11
12
public class FundsViewModel : TabItemCollectionViewModelBase<FundViewModel>
{
        private string _numberFund;
        private string _year;
        private string _keyPhrase;
        private string _page;
        public string NumberFund
        {
            get { return _year; }
            set { Set(ref _year, value); }
        }
//...
Как здесь привязать значения из формы к свойствам FundsViewModel

Добавить функции реагирующие на изменения свойств.
Миниатюры
Поиск дочернего элемента по имени в DependencyObject  
0
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
09.05.2019, 10:22  [ТС]
Text="{Binding Path=NumberFund, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Остался открытым вопрос с методом при изменении.

Так, чтобы он вызывался для конкретного экземпляра класса FundsViewModel

примерно так (3 других параметра поставил пока фиксированные)
C#
1
2
3
4
void ChangeNumberFund()
{
            Items = FundsViewModel.ListFundToCollectionFundViewModel(Fund.FindFund(0, _numberFund, null, null));
}
Добавлено через 59 минут
C#
1
2
3
4
5
public string NumberFund
{
            get { return _numberFund; }
            set { Set(ref _numberFund, value); ChangeNumberFund(); }
}

Items меняется, только отображается в Grid старые

Добавлено через 5 минут
Значения меняются, если переключится на другую вкладку и вернутся обратно, а сразу как?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.05.2019, 10:51
Цитата Сообщение от Archi0 Посмотреть сообщение
Зачем TabHostViewModelBase стал шаблоном не понятно, он же один в приложении.
Затем, что мы на выходе получили типизированный параметр и возможность в другой реализации задать другой тип. Будет ли реализация я понятия не имею. Я вообще много о чём понятия не имею по приложению, так что есть как есть. У меня же нет чёткого ТЗ.

Цитата Сообщение от Archi0 Посмотреть сообщение
Так работает
Этот момент не понял. Всё, что я запушил в репозиторий тоже работает, иначе я бы этого не делал.

Добавлено через 1 минуту
По остальному позже посмотрю или кто-то ещё подскажет.

Добавлено через 4 минуты
И ещё по первой цитате. Этот класс базовый, неважно сколько у нас реализаций, он если базовый, то он и должен быть базовым во всём, а не только названием и отсутствиеим реализации несколькоих методов, но параметр внезапно конкретный для конкретной реализации, что уже просто неправильно.
0
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
09.05.2019, 10:58  [ТС]
Исправил. Так Grid обновляется сразу

C#
1
2
3
4
5
6
7
8
9
10
void ChangeNumberFund()
{
            //Items = FundsViewModel.ListFundToCollectionFundViewModel(Fund.FindFund(0, _numberFund, null, null));
            Items.Clear();
            List<Fund> funds = Fund.FindFund(0, _numberFund, null, null);
            foreach (Fund fund in funds)
            {
                Items.Add(new FundViewModel().FundToFundViewModel(fund));
            }
}
0
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
09.05.2019, 17:53  [ТС]
Активность кнопки задаётся один раз и не меняется при изменении _page или Page
C#
1
2
3
4
5
6
7
PrevPageCommand = new RelayCommand(() =>
            {
                if (_page > 1) Page = (_page - 1);
            },()=>
            {
                return _page > 1;
            });

C#
1
2
3
4
5
6
7
8
public int Page
        {
            get { return _page; }
            set {
                if (value >= 1) Set(ref _page, value);
                else throw new Exception();
                ChangeFunds(); }
        }
Как правильно сменить активность кнопки. Page -> Set там думаю при условии _page == 1 | != 1 нужно менять.
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
09.05.2019, 19:33
Думаю, как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        public int Page
        {
            get { return _page; }
            set
            {
                if (value >= 1)
                    Set(ref _page, value);
                else
                    throw new Exception();
 
                ChangeFunds();
                PrevPageCommand.RaiseCanExecuteChanged();
            }
        }
Добавлено через 1 минуту
А вот есть покруче подход: How to automatically call the CanExecute method when properties change with MVVM Light in Windows and Phone apps (AutoRelayCommand)

Добавлено через 9 минут

Не по теме:

Ещё по поводу кода хотел бы заметить момент. Чтобы код выглядел нормально, а не "первая строка начинается без отступа" нужно копировать код полностью с начала строки, а не начала ключевого свойства, вроде очевидно, но я поначалу так же копировал. Просто выглядит небрежно как-то. Лично мне "режет глаз". Поэтому, собственно, и пишу )

1
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
10.05.2019, 11:26  [ТС]
Soure Grid находится в FundsViewModel.
А если по двойному нажатию на строку или определённой ячейки в строке нужно выполнить команду AddTabCommand
реализованную в MainViewModel. И передать в качестве параметра значение из строки или строку FundViewModel.

XML
1
2
3
4
5
6
                            <DataGrid.InputBindings>
                                <MouseBinding
                                    MouseAction="LeftDoubleClick"
                                    Command="{Binding AddTabCommand}">
                                </MouseBinding>
                            </DataGrid.InputBindings>
Так нет реакции на LeftDoubleClick. Как эту команду привязать?

Добавлено через 4 часа 15 минут
Это работает с командой определённой в FundsViewModel, но почему то, если строка не выделена.
XML
1
2
3
4
5
6
                            <DataGrid.InputBindings>
                                <MouseBinding
                                    MouseAction="LeftDoubleClick"
                                    Command="{Binding TestCommand}"
                                    CommandParameter="{Binding Items/}"/>
                            </DataGrid.InputBindings>
нужно AddTabCommand запускать

Добавлено через 48 минут
Решил
Конструктор поменял

C#
1
2
3
4
5
       public FundsViewModel(ICommand AddTabCommand)
        {
                        //...
                        OpenFundCommand = AddTabCommand;
        }
Просто присвоил команде OpenFundCommand команду AddTabCommand
в качестве параметра передался FundViewModel строки по которой сделали LeftDoubleClick
(только по прежнему, если строка была не выбрана, там возможно в стилях что-то)
0
31 / 17 / 5
Регистрация: 18.07.2013
Сообщений: 220
13.05.2019, 13:26  [ТС]
Не то передаёт
XML
1
CommandParameter="{Binding Items/}"/>
результат первая строка из Items
XML
1
CommandParameter="{Binding Items[1]}"/>
Так будет вторая строка из Items, а как передать ту строку по которой сделали двойное нажатие?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.05.2019, 13:26

Передача имени файла при создании дочернего процесса
Только начинаю программировать под Linux и не совсем понимаю, как это работает Задача такая: Родительский процесс создает n дочерних...

Отрисовка дочернего элемента
Здравствуйте. Зашел в тупик и никак не могу разобраться. Есть компонент представляющий из себя кнопку, которая отрисовывается в сообщении...

Поиск файлов по части имени \ имени
var SR: TSearchRec; Folder: String; begin Folder := 'D:\'; Folder := IncludeTrailingPathDelimiter(Folder); if...

Выбор дочернего элемента Stackpanel
привет есть stackpanel в ней элементы label Нужно через код обратится и выбрать что в нем написано, например к 3тему лейболу как это...

Добавление дочернего элемента в XML
Собственно сразу покажу часть кода _di_IXMLDocument XMLDocument= NewXMLDocument(); XMLDocument-&gt;LoadFromFile(FileName); IXMLNode...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru