How stretch grid created from data template across entire cell in XAML? - c#

I'm looking for a way to display a nested grid across the entire cell of a parent grid (content). The nested grid (menuContentControl) is created with a data template. The buttons in the nested grid should fill the cells. I create the nested grid and set the row / column with the following code:
ContentControl menuContentControl = new ContentControl();
menuContentControl.Content = this.menuViewModel;
menuContentControl.ContentTemplate = this.MenuDataTemplateLeft;
Grid.SetRow(menuContentControl, 1);
Grid.SetColumn(menuContentControl, 1);
this.content.Children.Add(menuContentControl);
The data template for menuContentControl:
<DataTemplate x:Name="MenuDataTemplateLeft">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="button_1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding MenuEntry1Description}" Grid.Row="0" Grid.Column="0"/>
<Button x:Name="button_2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding MenuEntry2Description}" Grid.Row="0" Grid.Column="1"/>
</Grid>
</DataTemplate>
Setting the horizontal and vertical aligment of the data template grid to 'stretch' does not work. Any ideas? Thank you :)

Related

Expand the Grid with when the Expander is expanded

I have a problem designing my GUI in wpf.
How do i set the Grid ColumnDefinition Width dynamically,
I have a expander. And when the expander is clicked the grid should also expand and adjust with the size of the expander
As of now i have this GUI
enter image description here
And this is the xaml code
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="127"/>
<ColumnDefinition Width="665*"/>
</Grid.ColumnDefinitions>
<Expander Background="Gray" x:Name="expander" ExpandDirection="Right" Expanded="Expander_Expanded" >
<Expander.Header>
<TextBlock Text="Objects">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<StackPanel Margin="10,4,0,0">
<CheckBox Margin="4" Content="Option 1" />
<CheckBox Margin="4" Content="Option 2" />
<CheckBox Margin="4" Content="Option 3" />
</StackPanel>
<!-- Stuff XD -->
</Expander>
<Grid Grid.Column="1" Background="Red"/>
</Grid>
As of now the ColomnDefinition width is 127
I want it to adjust to at least 30. So the window will be filled with other stuff
like this
enter image description here
But my problem is how do i expand the grid when the expander is expanded.
And another thing. I can't get the size of the expander when expanded. It gives me NaN which i can't use to set the columndefinition width
Thank you so much. Sorry for my bad english
Use Auto in first column Width and it will define size of expander based on content.
If you would like that column "0" has some min Width just set the property MinWidth. (but in that case I will not recommend, but show below)
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="30"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
Also I will recommend use GridSplitter, then you will have splitter between two columns that allows to change width of columns by user in UI
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="30"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="DarkSalmon"/>
Also in expander you can only have one user-control, so "stuff" you said need to be inside some layout control like stack-panel,dock or another grid etc.
Let me know if it works as you expected.

How to structure a stacked form with WPF XAML?

On my Window, I've got a GroupBox. I'd like to build out a horizontally aligned form inside of that GroupBox. By horizontally aligned, I mean a form where the label and the input reside on the same grid row or x axis. Separate form labels + inputs reside on their own row.
Since a GroupBox can only have one child content, I assume I need to either use a Grid or StackPanel. I'm trying to use a StackPanel because that seems simpler and should achieve what I'm aiming for.
The issue I'm trying to figure out is how to group the input and label into one unit so they can reside horizontally next to each other, but stack vertically as a pair within the StackPanel.
It's probably best to use a Grid that way you an get the labels and inputs to line up vertically. While it's not impossible with a stack panel it's a whole lot harder. If you set the grid's RowDefinition heights to "Auto" the grid will only be as tall as it needs to be:
<GroupBox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Label1"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Input1}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Label2"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Input2}"/>
etc.
</Grid>
</GroupBox>
You'll probably need to play around with margins and/or padding and horizontal alignments to get the layout exactly how you want it, but this should give you the control you need to achieve what you want.
you can use a stackpanel with orientation equal to vertical inside your groupbox and inside that stackpanel you can have another stackpanel with orientation equal to horizantal for your label and input just like following sample code.
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical">
<StackPanel Name="input1" Orientation="Horizontal">
<Label Content="input1"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input2" Orientation="Horizontal">
<Label Content="input2"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input3" Orientation="Horizontal">
<Label Content="input3"/>
<TextBox/>
</StackPanel>
</StackPanel>
</GroupBox>
One feature you might find useful is grid shared size scope. It can help you align elements in multiple different Grids, by sharing their column\row sizes, like this:
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input11" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input2222222" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input3333333333333" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
</StackPanel>
</GroupBox>
I don't say that it is necessary in the code above, but that is just example. Often, you want to use grid in for example ItemTemplate of ItemsControl, and you want all items to be aligned. Here shared size scope might help.

Add ScrollViewer to only one column inside a grid

I'd like to add a scrollviewer to only 1 column in my grid, so that the left column stay fixed, while the right columns can scroll. Also, my right column is a tabpanel, i'd like to be able to scroll only the content.
This is what i currently have : but the whole page keeps scrolling.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<max:MaxListBox Margin="2" VerticalAlignment="Stretch" Width="100" x:Name="lsbYear" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=WorkingEntity.PayrollFormulas.Periods}"/>
<max:MaxTabControl Grid.Column="1" Margin="2">
<max:MaxTabItem FieldDescription="Enum:PayrollProvincesType.Federal">
<ScrollViewer>
<!-- content for this tab -->
</ScrollViewer>
</max:MaxTabItem>
<max:MaxTabItem FieldDescription="Enum:PayrollProvincesType.Quebec">
<ScrollViewer>
<!-- content for this other tab -->
</ScrollViewer>
</max:MaxTabItem>
</max:MaxTabControl>
</Grid>
Example :

Last grid rows are displayed on top of each other in wpf

I'm adding rows to a grid in the code behind, but each time some of the rows at the end get displayed on top of each other (overlapping; as though they were in the same row). I know that the row numbers I'm setting are not the same, and that each row has a height of auto.
The grid has no fixed height but is within a tab header of fixed height. I'm using a scroll bar with the grid and that works fine (it expands when I add more items), but there are always some number of rows at the end that are overlapping. So it's not like the grid is only accepting a fixed number or is staying at a fixed length. Even if I add a few rows, and the grid only takes up half the screen, the last couple of rows will be overlapping at the end.
Nothing I try to do with the grid seems to change anything - I tried setting the height to auto, to a fixed height, it was all the same. I'm really confused as to what is going on.
Any suggestions would be extremely appreciated. I know a DataGrid might work better here but for now I need to stick with this grid.
This is my xaml code:
<TabControl Grid.ColumnSpan="5" Grid.RowSpan="15" Height="640">
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Height="23" VerticalAlignment="Center">
<Image Source= "image.png" Margin="0,-3,0,0" VerticalAlignment="Center" Height="17" />
<TextBlock Margin="5,0,0,0" VerticalAlignment="Center">text</TextBlock>
</StackPanel>
</TabItem.Header>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid Name="myGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="5"/>
<RowDefinition Height="1"/>
<RowDefinition Height="20"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
</Grid>
</ScrollViewer>
</TabItem/
...
And in the code behind I am adding rows (to the existing ones) in this way:
RowDefinition rowNew1 = new RowDefinition();
rowNew1.Height = new GridLength(1, GridUnitType.Auto);
myGrid.RowDefinitions.Add(rowNew1);
TextBlock tb = new TextBlock();
tb.Text = some_string;
myGrid.Children.Add(tb);
tb.Margin = new Thickness(10, 0, 0, 0);
Grid.SetRow(tb, some_number);
Works fine for me. Make sure the row number you're setting it to is in fact the correct index:
Grid.SetRow(tb, myGrid.RowDefinitions.IndexOf(rowNew1));

C# Change backgroundcolor specific row

I've created a new project from the Grid App (XAML) template (C# Windows Store).
So far I've changed nothing in the template, but I would like to change the backgroundcolor from a specific row in the grid.
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
I would like to change the backgroundcolor from row 0 (which contains the page title).
Any ideas?? Thanks in advance!
This row consits of:
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Grid.Column="1" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
You can't set the background color on the Grid.Row itself, instead set the Background property on whatever occupies this row.
For example
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Background="Red" Grid.Row="0">
<TextBlock>Test</TextBlock>
</Grid>
</Grid>
EDIT:
Updated for Silverlight; TextBlock doesn't have Background so you have to put the control in another Border or grid container which does have background. Code updated to reflect this.
How about inserting border where you need it
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Background="Red" Grid.ColumnSpan="1"></Border>
<TextBlock>Test</TextBlock>
<Border Background="blue" Grid.Row="1" Grid.ColumnSpan="1"></Border>
<TextBlock Grid.Row="1">Test2</TextBlock>
</Grid>
note that you can especify the columns span in case of include more columns

Categories