Привязка данных к выбранному TreeViewItem, только если дочерний элемент другого TreeViewItem - PullRequest
0 голосов
/ 11 июля 2011

У меня есть пользовательский класс (NewBlockLabelInfo) с наблюдаемой коллекцией другого пользовательского класса (DoorControllerLabelInfo). Я успешно связал класс NewBlockLabelInfo с древовидной структурой, и все отображается нормально.

У меня есть много текстовых полей, которые привязаны к определенным свойствам данных, и их обновление отражается в виде дерева.

Я бы хотел привязать один набор текстовых полей для свойств к выбранному элементу в древовидной структуре, ЕСЛИ выбранный элемент является дочерним по отношению к указанному элементу дерева (Observable Collection, Door Controllers)

Контекст данных указывается на уровне окна.

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

Вот XAML WPF для TreeView

<TreeView Margin="12,150,582,16" Name="treeView1">
            <TreeViewItem Header="{Binding Path=BlockName}" Style="{StaticResource BlockItem}" IsExpanded="True">
                <TreeViewItem Style="{StaticResource PhoneNoItem}" Header="{Binding Path=TelephoneNumber}"/>
                <TreeViewItem Style="{StaticResource DataNoItem}" Header="{Binding Path=DataNumber}"/>
                <TreeViewItem Style="{StaticResource CompanyItem}" Header="{Binding Path=CompanyName}"/>
                <TreeViewItem Style="{StaticResource ConnectedItem}" Header="{Binding Path=ConnectedDC}" />
                <TreeViewItem IsExpanded="True" Header="Door Controllers" Foreground="#FF585858" ItemsSource="{Binding Path=DoorControllers, UpdateSourceTrigger=PropertyChanged}" Name="DCTreeViewItem" Selected="DCTreeViewItem_Selected">
                    <TreeViewItem.ItemTemplate>
                        <HierarchicalDataTemplate>
                            <TreeViewItem Header="{Binding Path=DCName}" Style="{StaticResource DCItem}" IsExpanded="True" Selected="DCTreeViewItem_Selected" >
                                <TreeViewItem Header="{Binding Path=Address}" Style="{StaticResource AddressItem}" />
                                <TreeViewItem Header="{Binding Path=Channel1}" Style="{StaticResource Door1Item}" />
                                <TreeViewItem Header="{Binding Path=Channel2}" Style="{StaticResource Door2Item}" />
                            </TreeViewItem>
                        </HierarchicalDataTemplate>
                    </TreeViewItem.ItemTemplate>
                </TreeViewItem>
                <TreeViewItem IsExpanded="True" Header="Flats" Foreground="#FF585858" ItemsSource="{Binding Path=FlatNames, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
                    <TreeViewItem.ItemTemplate>
                        <DataTemplate>
                            <TreeViewItem Header="{Binding}" Style="{StaticResource FlatsItem}" IsExpanded="True">
                            </TreeViewItem>
                        </DataTemplate>
                    </TreeViewItem.ItemTemplate>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>

Как привязать текстовое поле к выбранному свойству элемента (или к свойству класса с привязкой к данным) TreeViewItem, только если оно является дочерним элементом для контроллеров дверей TreeViewItem

Заранее спасибо Оливер

Ответы [ 2 ]

0 голосов
/ 12 июля 2011

Я решил это сам, добавив обработчик событий по щелчку для каждого из дочерних TreeViewItems, которые меня интересуют.С этим я мог тогда получить DataContext из него, и установить его как DataContext TextBoxs, и создать мои собственные привязки.

Поскольку извлечение DataContext выполняется по ссылке, а не по значению, это работает.

Вот обработчик события для того, когда один из дочерних узлов нажал, чем меня интересует: (Простите за временное именование)

private void DCTreeViewItem_Selected(object sender, RoutedEventArgs e)
    {
        TreeViewItem currentItem = (TreeViewItem)e.OriginalSource;

        textBox5.DataContext = ((DoorControllerLabelInfo)currentItem.DataContext);

        Binding b = new Binding("DCName");
        b.Mode = BindingMode.TwoWay;
        b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

        BindingOperations.SetBinding(textBox5, TextBox.TextProperty, b);
    }

Из этого я устанавливаю путь, привязкуmode и источник обновления триггера в XAML, так что требуется обновить только контекст данных.

Спасибо, Оливер

0 голосов
/ 11 июля 2011

Скорее всего, вам лучше всего определить селектор DataTemplate и создать несколько шаблонов данных.Селектор может оценивать все виды логических правил и возвращать нужный шаблон.

Вот очень хорошее начало работы учебник по DataTemplateSelectors .

РЕДАКТИРОВАТЬ

После перечитывания вашего вопроса вот что я получил.

Есть ли в ваших модельных классах свойства навигации для перехода к родительским объектам?Если это так, вы можете использовать триггерные (или более предпочтительные, если вы используете MVVM) свойства ViewModel для включения / отключения / изменения видимости в зависимости от того, какой родительский объект является родительским TreeViewItem.Немного сложнее получить доступ к визуальному дереву, как вы описываете.

...