tags:

views:

9

answers:

0

I've been busy with WPF for quite some time, but I keep struggling with WPF commands. One thing I keep wondering is how the following problem should be solved.

I want the button outside the TabControl to send commands to the templated TextBox within the TabControl:

<StackPanel>
    <StackPanel.Resources>
        <Collections:ArrayList x:Key="documents">
            <System:String>Document1</System:String>
            <System:String>Document2</System:String>
            <System:String>Document3</System:String>
        </Collections:ArrayList>
    </StackPanel.Resources>

    <!-- I want this button to send its command to the templated 'editBox'
      -- in the TabControl below, but I've got no clue what fill in for
      -- the CommandTarget! -->
    <Button Content="Select All"
            Command="ApplicationCommands.SelectAll" 
            CommandTarget="{Binding ElementName=tabCtl, Path=SelectedItem}" />
    <TabControl Name="tabCtl" 
                ItemsSource="{Binding Source={StaticResource documents}}">
        <!-- Left out TabControl.ItemTemplate for simplicity -->
        <TabControl.ContentTemplate>
            <DataTemplate>
                <StackPanel>
                    <!-- This button works, easy one -->
                    <Button Content="Select All"
                            Command="ApplicationCommands.SelectAll" 
                            CommandTarget="{Binding ElementName=editBox}" />
                    <TextBox Name="editBox" Text="{Binding Path=.}"/>
                </StackPanel>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</StackPanel>

The background is that I'm constructing an app which can open several documents in a tabbed view. I made a a 'Document' class (part of my data model, has no knowledge of wpf), and I made a 'DocumentView' UserControl class which is capable of showing (and editing) a Document. DocumentView can handle custom RoutedCommands, which are sourced by buttons in a toolbar outside the tabcontrol.

The ArrayList with strings in the example represents an ObservableCollection of Document instances in my real application. The TextBox in the DataTemplate is the DocumentView.

The CommandTarget="{Binding ElementName=tabCtl, Path=SelectedItem}" obviously doesn't work (String is not capable of receiving a Command, duh), but "Path=SelectedContent" doesn't work either: SelectedContent returns the String, not the StackPanel from the DataTemplate.

This looks like a very common problem to me, but I spend hours on Google trying to find other WPF applications doing something comparable. Maybe I do not understand the WPF way of working altogether, and my Document/DocumentView contruction is bad (in the context of WPF)?

I asked a comparable question before without any real success, but I think this one is a bit more clear and simpler.