Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF .NET4.0 re-use same instance of UserControl

Tags:

c#

wpf

.net-4.0

I'd like to display the same instance of user control twice. Ive tried doing the following:

<UserControl.Resources>
    <Views:MyControl View x:Key="_uc1" MinHeight="300"/>
</UserControl.Resources>

And trying to use it in a TabControl:

<TabControl Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" >
    <TabItem >
        <TabItem.Header>
            <TextBlock Text="Header1" FontWeight="13"/>
        </TabItem.Header>

        <StackPanel  >
            <ContentControl Content="{StaticResource _uc1}"/>
        </StackPanel>
    </TabItem>
    <TabItem >
        <TabItem.Header>
            <TextBlock Text="Header2" FontWeight="13"/>
        </TabItem.Header>

        <StackPanel MinHeight="600" >
            <ContentControl Content="{StaticResource _uc1}"/>
        </StackPanel>
    </TabItem>
</TabControl>

Im getting the error message: "{"Specified element is already the logical child of another element. Disconnect it first."}"

Is what Im trying to achieve possible?

Thanks,

like image 625
TheRRRanger Avatar asked May 24 '11 03:05

TheRRRanger


2 Answers

It's not. As the error indicates, a given object may only be present in a given logical tree once. This helps to ensure that the logical tree remains a tree.

If you're using the MVVM pattern (or are just using DataBinding in general,) then you can bind two different UserControls to the same backing ViewModel/data, so that the controls will behave the same and operate on the same state representation. You'll still need two different controls, though.

like image 79
dlev Avatar answered Oct 14 '22 11:10

dlev


In WPF (and Silverlight) a control cannot be in more than one place in the visual tree. What you can do is have two separate instances of the user control, but bind their relevant properties to the same underlying source.

For example, let's say you had a Contact object and you wanted two MyControl instances to refer to the same FullName property.

<UserControl>
    <UserControl.Resources>
        <my:Contact x:Key="data" FullName="Josh Einstein" />
    </UserControl.Resources>
    <TabControl DataContext="{StaticResource data}">
      <TabItem>
        <TabItem.Header>
          <TextBlock Text="Header1" FontWeight="13" />
        </TabItem.Header>
        <StackPanel>
          <!-- instance #1 -->
          <Views:MyControl FullName="{Binding FullName, Mode=TwoWay}" />
        </StackPanel>
      </TabItem>
      <TabItem>
        <TabItem.Header>
          <TextBlock Text="Header2" FontWeight="13" />
        </TabItem.Header>
        <StackPanel>
          <!-- instance #2 -->
          <Views:MyControl FullName="{Binding FullName, Mode=TwoWay}" />
        </StackPanel>
      </TabItem>
    </TabControl>
</UserControl>

If you just want a single control to appear in multiple places in the visual tree, but not actually be interactive, you can use a VisualBrush to "paint" onto another control.

like image 22
Josh Avatar answered Oct 14 '22 11:10

Josh