I have a grid with 2 rows and 4 columns with width and height as specified below. Second row has only one control in col=1 and that control may or may not present(due to some logic).
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions></Grid>
When control is not present:
Since second row is height is "Auto" and when I have no control, I'll have only single row. In that case, I need to have specific margin with respect to grid bottom. Hence, Margin of row 0 control = "0,0,0,14"
When control is present:
When control is present, I have two rows and I need to have margin between two row elements as 6px and second row margin should be 14 w.r.t bottom of grid. Hence, Margin of row 0 control = "0,0,0,6" and Margin of row 1 control = "0,0,0,14"
How could I achieve these different margin values based on second row presence. Please help. Thanks in advance. Refer img:
For your requirement, you could use MarginConverter
to set row 0 control margin base on the row 1 control's present or not.
For example
public class MarginConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
Thickness newMargin;
var visibility = (Visibility)value;
switch (visibility)
{
case Visibility.Visible:
newMargin = new Thickness(0, 0, 0, 6);
break;
case Visibility.Collapsed:
newMargin = new Thickness(0, 0, 0, 14);
break;
default:
break;
}
return newMargin;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Usage
<Page.Resources>
<local:MarginConverter x:Key="Conveter" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle
Grid.Row="0"
Grid.Column="1"
Margin="{Binding ElementName=Row1Control, Path=Visibility, Converter={StaticResource Conveter}}"
Fill="Red" />
<Rectangle
x:Name="Row1Control"
Grid.Row="1"
Grid.Column="1"
Height="80"
Margin="0,0,0,14"
Fill="Black"
Visibility="Visible" />
</Grid>
Update
But in my case, Row1Control is dynamically set in the backend.
you could detect RootGrid LayoutUpdated
event, if you add the control it will be invoked, then re-set MarginProperty in the following method.
private int oldCount;
private void RootGrid_LayoutUpdated(object sender, object e)
{
if(RootGrid.Children.Count > oldCount)
{
if (RootGrid.Children.Any(p => p.GetValue(NameProperty).ToString() == "Row1Control"))
{
Row0Control.SetValue(MarginProperty, new Thickness(0, 0, 0, 6));
}
else
{
Row0Control.SetValue(MarginProperty, new Thickness(0, 0, 0, 14));
}
oldCount = RootGrid.Children.Count;
}
}
Add element in the code behind.
private void Button_Click(object sender, RoutedEventArgs e)
{
var Row1Control = new Rectangle() { Height = 80, Margin = new Thickness(0, 0, 0, 14), Fill = new SolidColorBrush(Colors.Black), Name = "Row1Control" };
Row1Control.SetValue(Grid.ColumnProperty, 1);
Row1Control.SetValue(Grid.RowProperty, 1);
RootGrid.Children.Add(Row1Control);
}