views:

231

answers:

3

I have a page in which I have a grid with 2 columns, one accommodating 80* width and the other accommodating 20*. Beneath the grid is a stack panel to which I load UI elements (child stack panels) at runtime.

My objective is to bind the widths of the stackpanels to the columns of the grid. This works perfectly and the stackpenels resize if the dynamic content is mocked to be static in the design view. But when the application is run, the bindings fail and the widths are not bound.

Is there any way to refresh the bindings so that I can notify the stackpanels to refer the widths of the grid and configure its's size?

Updated: This is what my XAML looks like:

<Page x:Class="WPFTestApp.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Page1">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid x:Name="resizeGrid"
              Grid.Column="0" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="leftColumn"
                                  Width="80*" />
                <ColumnDefinition x:Name="rightColumn"
                                  Width="20*" />
            </Grid.ColumnDefinitions>            
        </Grid>

        <StackPanel x:Name="contentPanel"
                    Grid.Column="0" Grid.Row="0" >
            <!-- Dynamic StackPanels are added here -->
        </StackPanel>
    </Grid>
</Page>

In my code, I create StackPanel elements and add it to the contentPanel by saying: contentPanel.Children.Add(...);

Unfortunately, I HAVE to use StackPanels here. :-(

The markup of a dynamically created StackPanel element is as follows (note that I use a Binding to the grid already in the XAML):

<StackPanel x:Name="element01"
             Orientation="Horizontal"
             Width="{Binding ElementName=resizeGrid, Path=ActualWidth}" >
    <StackPanel x:Name="leftPanel"
                Orientation="Vertical"
                Width="{Binding ElementName=leftColumn, Path=ActualWidth}">
        <!-- Content goes here -->
    </StackPanel>
    <StackPanel x:Name="rightPanel"
                Orientation="Vertical"
                Width="{Binding ElementName=rightColumn, Path=ActualWidth}">
        <!-- Content goes here -->
    </StackPanel>
</StackPanel>

The XAML code for my dynamic StackPanel elements are generated through an XSLT transformation

Note the xmlns:x namespace dynamic StackPanel. This also has to be done because of it being generated through XSLT

Thanks in advance!

A: 

As far as I know setting the Width of a StackPanel with Orientation="Horizontal" will have no effect. The size of a StackPanel does not exceed the size of its content in its oriented direction.

Why do you "HAVE" to use StackPanels here? You almost certainly want DockPanels, given your objective. You won't have to bind or set anything, because the DockPanel will fill the cell automatically.

Jay
I "HAVE" to use StackPanels because I have no control of what's being generated from the XSLT transformation. :-( Modifying the XSLT is out of the question, so I have to make do with an alternative.
shehandavy
A: 

Try binding the ActualWidth instead of Width.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid x:Name="resizeGrid"
          Grid.Column="0" Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="leftColumn"
                              Width="{Binding ElementName=contentPanel, Path=ActualWidth}" />
            <ColumnDefinition x:Name="rightColumn"
                              Width="*" />
        </Grid.ColumnDefinitions>
    </Grid>       


    <StackPanel x:Name="contentPanel"
                Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" >
        <StackPanel Background="Yellow" Width="100" Height="25" />
        <StackPanel Background="Green" Width="120" Height="25" />
        <StackPanel Background="Red" Width="140" Height="25" />
        <TextBlock Background="Gray" Text="{Binding ElementName=contentPanel, Path=ActualWidth}" />
    </StackPanel>
</Grid>

The following changes I have done above:
1) Set the leftColumn to the ActualWidth of the contentPanel
2) Set the rightColumn to *
3) contentPanel HorizontalAlignment should be changed other then Stretch. Here I have changed it to Left

HTH

Avatar
Oops question updated !
Avatar
A: 

I found a solution for this issue. (Sorry for the late response)

What I did was, I cut and pasted the "resizeGrid" Grid control into the "contentPanel" Stackpanel.

As I mentioned above, the contents within the contentPanel are generated through an XSLT transformation and this surely creates a namespace reference issue. I noticed "element not found..." message in the Output window whenever this Window is loaded - this proved me right.

Inserting the "resizeGrid" into the "contentPanel" helped because then both the controls are within the same namespace and can be referenced for a PropertyBinding using "ElementName" attribute.

Thank you for your support! :-)

shehandavy