tags:

views:

692

answers:

3

In ASP.NET I could make a user control to occupy more than one cell in a table on the page:

UserControl1:

<tr>
  <td>foo</td>
  <td>bar</td>
</tr>

Page1:

<table>
  <put a UserControl1 here/>
  <put another UserControl1 here/>
</table>

and the column widths adjusted automatically to fit the largest user control.

Can this be done in WPF too ? How ?

I think that user controls can't do that, and I must create a simple class instead of a user control, which has a method to add everything to the grid. But that way everything should be done by code, xaml is useless here.

+1  A: 

No you can't do anything like that in XAML.

ASP.NET user controls emit HTML. Your user control emits the HTML for a table row. Given that the emitted markup makes sense in the form's markup, what you do is possible, but not very good practice, since the control depends entirely on the markup in the page to make any sense at all. Besides, the size and placement of the control in the page should be the page's responsibility, not the control's. It's all about encapsulation.

WPF controls don't emit markup, of course. Rather, they are instantiated in the WPF window/page, and live as visual controls in the window. A different situation entirely.

To make your control span several columns, you should use the Grid.ColumnSpan extension attribute, like this:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <MyControl Grid.ColumnSpan="2" Name="myControl">Button</Button>
</Grid>
Tor Haugen
A: 

I would not recommend having the user control define how it should occupy table/grid cells in a host. The page/window hosting the user control should define how the user control should be displayed. That way you can place the user controls in a WPF grid, and use Grid.ColumnSpan attribute to make the user control occupy multiple columns in the grid.

The control will end up being much more usable, and seperation of resonsability is kept.

Thies
+1  A: 

I've found the answer here.

It can be done with SharedSizeGroup and Grid.IsSharedSizeScope.

UserControl1.xaml:

<UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="SharedSizeGroup1"/>
            <ColumnDefinition SharedSizeGroup="SharedSizeGroup2"/>
        </Grid.ColumnDefinitions>
        <Label Name="Label1" Grid.Column="0">Label1</Label>
        <Label Name="Label2" Grid.Column="1">Label2</Label>
    </Grid>
</UserControl>

Window1.xaml:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:y="clr-namespace:WpfApplication1">
    <Grid Grid.IsSharedSizeScope="True">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <y:UserControl1 Grid.Row="0" x:Name="UserControl1A"/>
        <y:UserControl1 Grid.Row="1" x:Name="UserControl1B"/>
    </Grid>
</Window>

Window1.xaml.cs:

using System.Windows;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            UserControl1A.Label1.Content = "Label1WithLongText";
        }
    }
}
csuporj