开发者

How do you navigate a complex Visual Tree in order to re-bind an existing element?

How do you navigate a complex Visual Tree in order to re-bind an existing element?

In the above image, child is a ContentPresenter. Its Content is a ViewModel. However, its ContentTemplate is null.

In my XAML, I have a TabControl with the following structure:

<local:SuperTabControlEx DataContext="{Binding WorkSpaceListViewModel}"
 x:Name="superTabControl1" CloseButtonVisibility="Visible" TabStyle="OneNote2007" ClipToBounds="False" ContentInnerBorderBrush="Red" FontSize="24" >
            <local:SuperTabControlEx.ItemsSource>
                <Binding Path="WorkSpaceViewModels" />
            </local:SuperTabControlEx.ItemsSource>

                <TabControl.Template>
                <ControlTemplate
                    TargetType="TabControl">
                        <DockPanel>
                            <TabPanel
                            DockPanel.Dock="Top"
                            IsItemsHost="True" />
                            <Grid
                            DockPanel.Dock="Bottom"
                            x:Name="PART_ItemsHolder" />
                        </DockPanel>
                        <!-- no content presenter -->
                    </ControlTemplate>
                    </TabControl.Template>

            <TabControl.Resources>
            <DataTemplate DataType="{x:Type vm:WorkSpaceViewModel}">

            ....

WorkSpaceViewModels is an ObservableCollection of WorkSpaceViewModel. This code uses the code and technique from Keeping the WPF Tab Control from destroying its children.

The correct DataTemplate - shown above in the TabControl.Resource - appears to be rendering my ViewModel for two Tabs开发者_如何学C.

However, my basic question is, how is my view getting hooked up to my WorkSpaceViewModel, yet, the ContentTemplate on the ContentPresenter is null? My requirement is to access a visual component from the ViewModel because a setting for the view is becoming unbound from its property in the ViewModel upon certain user actions, and I need to rebind it.


The DataTemplate is "implicitly" defined. The ContentPresenter will first use it's ContentTemplate/Selector, if any is defined. If not, then it will search for a DataTemplate resource without an explicit x:Key and whose DataType matches the type of it's Content.

This is discussed here and here.

The View Model shouldn't really know about it's associated View. It sounds like there is something wrong with your Bindings, as in general you should not have to "rebind" them. Either way, an attached behavior would be a good way to accomplish that.


I think the full answer to this question entails DrWPF's full series ItemsControl: A to Z. However, I believe the gist lies in where the visual elements get stored when a DataTemplate is "inflated" to display the data item it has been linked to by the framework.

In the section Introduction to Control Templates of "ItemsControl: 'L' is for Lookless", DrWPF explains that "We’ve already learned that a DataTemplate is used to declare the visual representation of a data item that appears within an application’s logical tree. In ‘P’ is for Panel, we learned that an ItemsPanelTemplate is used to declare the items host used within an ItemsControl."

For my issue, I still have not successfully navigated the visual tree in order to get a reference to my splitter item. This is my best attempt so far:

// w1 is a Window
SuperTabControlEx stc = w1.FindName("superTabControl1") as SuperTabControlEx;
//SuperTabItem sti = (SuperTabItem)(stc.ItemContainerGenerator.ContainerFromItem(stc.Items.CurrentItem));

ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(stc);
//ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(sti);

DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;

The above code is an attempt to implement the techniques shown on the msdn web site. However, when I apply it to my code, everything looks good, except myDataTemplate comes back null. As you can see, I attempted the same technique on SuperTabControlEx and SuperTabItem, derived from TabControl and TabItem, respectively. As described in my original post, and evident in the XAML snippet, the SuperTabControlEx also implements code from Keeping the WPF Tab Control from destroying its children.

At this point, perhaps more than anything else, I think this is an exercise in navigating the Visual Tree. I am going to modify the title of the question to reflect my new conceptions of the issue.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜