Link to home
Start Free TrialLog in
Avatar of dineshwins
dineshwins

asked on

WPF Visual Inheritance

I have a user control in WPF, i want to use this use control as container control for other controls.

I have a user control which is having a grid with 3 rows, i want two rows(first and third) to be completly uneditable like it does in normal flow but the middle row should be open for user to place any control they want to place.
Avatar of saragani
saragani

Hi, in this case you should either inherit ContentControl instead of UserControl,
or have a DependencyProperty called Content and have a ContentControl or ContentPresenter in that that second row.
<UserControl x:Class="UserDefinedContentControl.MyContentControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Template>
        <ControlTemplate TargetType="{x:Type UserControl}">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <Border Background="Red" />
                <ContentPresenter Grid.Row="1"/>
                <Border Background="Blue"  Grid.Row="2"/>
            </Grid>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

[/code


Now you can do:
[code]
<Window x:Class="UserDefinedContentControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:UserDefinedContentControl"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:MyContentControl>
            <Button>
                Hello World
            </Button>
        </local:MyContentControl>
    </Grid>
</Window>

Open in new window

Avatar of dineshwins

ASKER

Thanks for the support, but in this way we could have only one content control in our user control, but i want to have multiple content controls inside my user control, what should i have to do to achieve this?
I was using here the content property.
Since you need several content propertied, then you need to add dependency properies that will accept your UI and show it in your user control in the right places
Will you please elaborate?
You wrote: " want two rows(first and third) to be completly uneditable like it does in normal flow but the middle row should be open for user to place any control they want to place."

That's what I gave you... Now you ask for something else: "but in this way we could have only one content control in our user control, but i want to have multiple content controls inside my user control"


So I don't understand what you want.... But here is a solution:


<UserControl x:Class="UserDefinedContentControl.MyContentControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">


    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Border Background="Red" /> 
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <ContentPresenter Grid.Column="0" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}, Path=Content1}"/>
            <ContentPresenter Grid.Column="1" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}, Path=Content2}"/>
            <ContentPresenter Grid.Column="2" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}, Path=Content3}"/>
        </Grid>
        <Border Background="Blue"  Grid.Row="2"/>
    </Grid>
</UserControl>

Open in new window



You can also have it like this:
(But you will get exception in the Visual Studio Designer)
<UserControl x:Class="UserDefinedContentControl.MyContentControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:local="clr-namespace:UserDefinedContentControl"
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Template>
        <ControlTemplate TargetType="local:MyContentControl">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <Border Background="Red" />
                <Grid Grid.Row="1">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <ContentPresenter Grid.Column="0" Content="{TemplateBinding Content1}"/>
                    <ContentPresenter Grid.Column="1" Content="{TemplateBinding Content2}"/>
                    <ContentPresenter Grid.Column="2" Content="{TemplateBinding Content3}"/>
                </Grid>
                <Border Background="Blue"  Grid.Row="2"/>
            </Grid>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

Open in new window






And have the Window contain that UserControl:
<Window x:Class="UserDefinedContentControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:UserDefinedContentControl"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:MyContentControl>
            <local:MyContentControl.Content1>
                <Button>
                    Content 1
                </Button>
            </local:MyContentControl.Content1>

            <local:MyContentControl.Content2>
                <Button>
                    Content 2
                </Button>
            </local:MyContentControl.Content2>

            <local:MyContentControl.Content3>
                <Button>
                    Content 3
                </Button>
            </local:MyContentControl.Content3>

        </local:MyContentControl>
    </Grid>
</Window>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of saragani
saragani

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Mate