Xaml - How to get exact row from grid (and change background) - c#

I have defined grid in xaml like this:
<Grid Name="grdMoney" HorizontalAlignment="Center" Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
... Content, many Textboxes in each row
</Grid>
Now I just want to highlight some row by changing background in that row. But I can't find out how can I get exact row from grid in code. I think it's easy but I am googling for last 15minutes and can't find it. Maybe something with grdMoney.Childer[number_of_row]? Thanks for help

Grid is a Panel. Panels are responsible for layouting, nothing more.
If you want to update background - put content of every row to Border, and find appropriate Border like that (i wrote code here, and didn't test it, but should work):
int desiredRowId = 2;
foreach(var child in grdMoney.Children.OfType<Border>())
{
if (Grid.GetRow(child) == desiredRowId)
{
child.Background = new SolidColorBrush(Colors.Red);
}
}

I've probably'll do this in xaml using DataTriger
In data triger you can check your condition and apply appropriate background

Related

Dynamically toggle visibility of WPF grid column from C# code

My problem is: I can't find out how to toggle the visibility of my WPF grid column. Assume following XAML markup:
<Grid x:Name="myGrid">
<Grid.RowDefinitions>
<RowDefinition x:Name="Row1" />
<RowDefinition x:Name="Row2" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
</Grid>
Aferwards the grid is filled with some controls etc. Now I want to hide a single column dynamically out of my C# code. I've tried achieving this by setting the the column's definition width to zero, e.g. Column1.Width = 0. This works, but I don't really like this solution - is there really no better way?
I'm looking for something like myGrid.Columns[0].Visibility = COLLAPSED or Column1.Visibility = HIDDEN. I just can't find something like that - any ideas?
<ColumnDefinition>
<ColumnDefinition.Style>
<Style TargetType="ColumnDefinition">
<Setter Property="Width" Value="*" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsColumnVisible}" Value="False">
<Setter Property="Width" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
Please do implement INotifyPropertyChanged in your ViewModel
The simplest way to do this is to add a named Grid as the top level control in the relevant column that you want to hide. Then you can just hide it and all of its contents as you would any other control:
In XAML:
<Grid x:Name="myGrid">
<Grid.RowDefinitions>
<RowDefinition x:Name="Row1" />
<RowDefinition x:Name="Row2" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
<Grid x:Name="GridColumn1" Grid.Column="1">
...
</Grid>
</Grid>
Then in code behind:
GridColumn1.Visibility = Visibility.Collapsed;
As you have more than one row in your Grid, you may want to rearrange them like this:
<Grid x:Name="myGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" />
<ColumnDefinition x:Name="Column2" />
</Grid.ColumnDefinitions>
<Grid x:Name="GridColumn0" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
<Grid x:Name="GridColumn1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</Grid>
UPDATE >>>
It is not really necessary to rearrange the main Grid like this... you could just as easily add two Grid controls, one in each row of the relevant column and then set the Visibility of them both together:
InnerGrid1.Visibility = InnerGrid2.Visibility = Visibility.Collapsed;
You could even add a Grid into each cell of the main Grid and have full control over which cells are visible at any one time.
In WPF Grid Column and Row Hiding on Code Project, they show a way using dependency properties. They set Visible = false, but internally, it sets Width = 0.
Another idea is to delete the column definition in code behind... But I guess it's an even worse hack! :(
An ugly hack would be to just change the width to 0 (out of sight, out of mind).
There are many reasons why you shouldn't do this but, based upon your situation, it may suffice!
Use following to Hide the grid. Similarly you can hide the row definitions and column definitions using Name property.
myGrid.Visibility = System.Windows.Visibility.Hidden;

WPF set menu height to fit?

In WPF, how can one set the height of menu to fit , instead of like this below where the gray shade goes down
<Window x:Class="XAML_Concepts.GridLayout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="GridLayout" Height="600" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Menu IsMainMenu="True" Grid.Row="0" Grid.ColumnSpan="2" Grid.RowSpan="1" >
<MenuItem Header="File">
<MenuItem Header="_New"></MenuItem>
<MenuItem Header="_Open"></MenuItem>
</MenuItem>
<MenuItem Header="Edit"></MenuItem>
</Menu>
</Grid>
</Window>
I just need it to look a normal menu, like one in windows explorer, without any gray shading below. I have tried manipulating row size, menu size, and several other attributes but I' missing something simple.
When I set the Grid''s row height to , say 20px , this is what I get which I am not pleased with because A-I don't want to enter an absolute height and B-The shade doesn't look right, it is like the background gradient is smearing..
Thanks
Try using this:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
This will cause the first row to shrink to only as much space as is necessary to display the content.
You must set the height of the row that your menu is located in to Auto. Like this:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
When a row or columns width or height is set to Auto, it only takes as much space as it needs.

Grid RowDefinitions trouble in Windows Phone 8

Critical problem here. In my case i assemble the below code for my application. Unfortunately, it creates the bigger problem in layout. Even we put RowDefinitions with Auto, it does not consider the RowHeight and goes underneath to the Bottom of the Windows Phone emulator.
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="firstGrid" Tap="FirstGrid_OnTap"/>
<Grid Grid.Row="1" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="A"/>
<Button Grid.Column="1" Content="B"/>
</Grid>
</Grid>
</Grid>
On loading of the page, it fills the firstGrid with the ImageBrush. Hence whenever user taps on the firstGrid, It will just insert one more row to the Grid by enabling the visibility of the second grid. This second grid will have couple of buttons. I astonished when i see the second grid because it hides in the bottom of the emulator. Even my hundred of different attempts , i am not able dig into the main problem which actually it has. Any help is much appreciated.
As per my understanding u need to make this change in code first row should be auto and second *.
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

WPF - Resizing controls within a window with resize

So I'm pretty new to WPF and I'm having trouble with the layout of my Window. Currently I have a WPF application with a Grid defined as such:
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
In the very top row, spanning two columns, I have a Menu. In the second row I have some Labels in the first column and an Image and a WindowsFormsHost in the second, finally, in the third row I have a graphing control in the second column. By default, I set the size of the Image and WFH to 570 x 413. Now, I'd like for both the Image and WFH to expand when my Window is resized such that they maintain the same relative (to the Window) size. (I actually would like the same to happen to my graphing control as well, but I can probably figure that one out if I can get the others. I cannot for the life of me figure out what setting I need to turn on/off or what I might need to bind or whatever in order to make this happen. Any help is greatly appreciated!
Thanks!
Have you tried:
<RowDefinition Height="*" />
Make sure to assign your Grid.Row within your image or control, but do not sign the controls height/width properties. The control should autosize with expansion.
Update
Did a quick test to make sure this works.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Example"/>
<Image Grid.Row="1" Source="c:\Example.jpg"/>
<Label Grid.Row="2" Content="Example2"/>
</Grid>
The image expands with the application based on the image's proportions. It does expand, but it keeps it's dimensions along with the full image in view. If you were to change the rowdefinition from ***** to Auto, you will notice that the image will expand, but it will expand past your view. Meaning you will not always see the full image.
I would suggest making a simple application like above, and playing with constraints to figure out what each does.
You need to show more information in your description, because all of the properties of the Grid and of the Image, etc. will factor into the layout.
However, you probably want to look at the HorizontalAlignment and VerticalAlignment properties of your Grid and of your Image, as well as the Stretch property of the Image. Also, you don't want to specify a fixed size for the image (you can specify a MinWidth and a MinHeight if you want them to be a certain size when starting up).
Here's a quick example that shows a grid filling a window, with a scaling image.
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Content="First Row" />
<Label Grid.Column="0" Grid.Row="1" Content="Column 0, Row 1" />
<Image Grid.Column="1" Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="Resources\ExamplePicture.png"
Stretch="Uniform" />

Dynamic RowDefinition Height

I have a simple xaml control with the following Grid Row definition:
<Grid.RowDefinitions>
<RowDefinition Height="15*" />
<RowDefinition Height="60*" />
<RowDefinition Height="20*" />
<RowDefinition Height="20*" />
<RowDefinition Height="15*" />
</Grid.RowDefinitions>
Rows 1-3 each hold a text block which may or may not have text in it. In the code behind I want to minimise the RowDefinition if there is no text. Essentially I have the following in my code behind:
if(textblock.Text != ""){
grid.RowDefinitions[elementRow].Height = new GridLength(20, GridUnitType.Star);
}
else{
grid.RowDefinitions[elementRow].Height = new GridLength(0, GridUnitType.Star);
}
I want rows 0 and 4 to stay as they are defined in the xaml. Unfortunatly this does not work even though there is text in the text block on row 2 nothing is displayed.
Am I doing something wrong.
Any help is appreciated,
James
Don't use the star notation, use Auto for your RowDefinitions. If the TextBlock.Text is empty, set the Visibility of the TextBlock to Visibility.Collapsed. The grid row will then automatically shrink to nothing.
This is not the answer to your question, just some info.
The * in the Height (or width for columns) means that the row (or column) width Height="*" (or Width="*") will take up the rest of the space. So if you have a grid with 4 rows in a grid with Height="100", if you do this:
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="10" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
The row width Height="*" will be 70 DIUs (device independent units).
Adding a number before the asterisk (Height="2*") only works if there are more than one rows using the asterisk, the number before the asterisk indicates how much more space will that specific row take (2* = twice as much, 3* three times as much, so on...). I. E.:
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="10" />
<RowDefinition Height="2*" /> <!-- this row will be twice as tall as the one below -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Here the 3rd row will have a height of 54 DIUs (twice as much as the 4th row which has a height of 26 DIUs approx.), both heights sum 80, which is the rest of the space of the grid (10 + 10 + 26 + 54 = 100, the grid height).
BTW, I agree with Charlie's answer.
You can put your items inside a UniformGrid with Columns="1" And make the TextBox Visibility to collapsed when you get emptry text.
<UniformGrid Columns="1">
<TextBlock Text="AAAA" Visibility="Collapsed" Grid.Row="0"/>
<TextBlock Text="BBBBB" Grid.Row="1"/>
<TextBlock Text="CCCCC" Grid.Row="2"/>
<TextBlock Text="DDDDD" Grid.Row="3"/>
<TextBlock Text="EEEE" Grid.Row="4"/>
</UniformGrid>

Categories

Resources