开发者

DataBinding to selected TreeViewItem only if child of other TreeViewItem

I have a custom class (NewBlockLabelInfo) with an observable collection of another custom class (DoorControllerLabelInfo) I've successfully databound the NewBlockLabelInfo class to the treeview, and everything displays fine.

I have a lot of textboxs that are data bound to certain properties, and updating these reflects in the treeview.

I'd like to databind one set of textboxs for the properties, to the selected item in the treeview IF the selected item is a child of the specified treeviewitem (Observable Collection, Door Controllers)

The Data Context is specified at the window level.

I've looked long and hard for a way to do this, let alone the best way.

Heres the WPF XAML for the 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开发者_如何学JAVA}" 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>

How can I bind a textbox to a selected item property (or to the databound class property) of a TreeViewItem only if it is a child of Door Controllers TreeViewItem

Thank you in advance Oliver


You would likely be best served with defining a DataTemplate selector, and creating several datatemplates. The selector can evaluate all kinds of logical rules, and return the template that you want.

Here is a pretty good getting started tutorial on DataTemplateSelectors.

EDIT

After rereading your question here is what I have got.

Do your model classes have navigation properties to get to parent objects? If so, you can use triggers (or more preferable if you are using MVVM) properties on the ViewModel to enable/disable/alter visibility based on what the parent object is rather than the parent TreeViewItem. It is a bit more difficult to access the visual tree the way you are describing.


I solved this myself by adding an event handler on click for each of the child TreeViewItems I am concerned with. With this I could then get the DataContext from it, and set it to be the DataContext of the TextBoxs, and create my own bindings.

Since DataContext retrieval is done by reference, and not by value this works.

Here is the event handler for when one of the child nodes are clicked than I am concerned with: (Forgive the temporary naming)

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);
    }

From this, I set the path, binding mode, and update source trigger in the XAML so that only the Data Context need to be updated.

Thanks Oliver

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜