tags:

views:

312

answers:

1

I've been using grids to hold my controls for a new app. Such as;

<Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Label1:" />
        <ListBox Grid.Row="0" Grid.Column="1" />                       

        <Label Grid.Row="1" Grid.Column="0" Content="Label2:" />
        <ComboBox Grid.Row="1" Grid.Column="1" />

        <Label Grid.Row="2" Grid.Column="0" Content="Label3:" />
        <TextBox Grid.Row="2" Grid.Column="1" />
    </Grid>

This works fine however I've now got a situation where I only want to show my third row based upon the selectedvalue from the combobox in the second row.

With a grid this seems a bit messy too set the visibilty of the entire row to be collapsed. I think I'd have to do it by setting the hight of the contents of the row to zero.

Is there a more flexible layout that the grid. I thought about the stackpannel but wasn't sure about having multiple columns and keeping the rows in synch.

This is probably a really simple question but I'm interested to get input from other people before I do anything.

Thanks.

+1  A: 

I wouldn't recommend setting the height of controls to zero - for one thing, it would still be possible to tab to a 0-height control which would be confusing for users to say the least :)

As an alternative, try binding the visibility of any affected controls to the combobox selection, e.g:

<UserControl xmlns:cnv="clr-namespace:your_namespace_here">
<Grid Margin="5">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label Grid.Row="0" Grid.Column="0" Content="Label1:" />
    <ListBox Grid.Row="0" Grid.Column="1" />                       

    <Label Grid.Row="1" Grid.Column="0" Content="Label2:" />
    <ComboBox Name="cbo" Grid.Row="1" Grid.Column="1" />

    <Label Grid.Row="2" Grid.Column="0" Content="Label3:" 
        Visibility="{Binding ElementName=cbo, Path=SelectedIndex,
            Converter={cnv:IntToVisibilityConverter}}" />
    <TextBox Grid.Row="2" Grid.Column="1" />
</Grid>

In code, put together a converter which returns the relevant Visibility type:

namespace your_namespace_here
{
public class IntToVisibilityConverter : MarkupExtension, IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int _value = (int)value;
        return (_value > 0) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}
}

Note that in this example, the converter will return Visiblity.Collapsed if the first item in the combo is selected, otherwise Visiblity.Visible.

Untested code, but the method is sound. Hope this is of some use!

Conan
I see what you mean. Makes sense.Thanks very much!
JTinley
`System.Windows.Controls.BooleanToVisibilityConverter` is built into the framework too if you don't need to write your own
qntmfred
Not in silverlight
Oliver Weichhold