How to dynamically remove values from Grid in XAML? - xaml

Am new to Xamarin.
Right now I have implemented a grid in the XAML, with one row and 5 columns.
The expectation is like, when the element in the 3rd column does not have any values to show(null or empty), it will be removed and the 4th column element comes to 3rd and 5th column element comes to 4th.
How is this achievable?
Thanks much in advance.

You can change the Height property to hide the row of Grid in the RowDefinition.
With one Row hidden :
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
<RowDefinition Height="0" /> <-- this row is hidden-->
</Grid.RowDefinitions>
With all rows shown :
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
You can also bind the Height to a property of your ViewModel.
public GridLength GridRowHeight { get; set; }

Related

Narrator narrating UI element with `isTabStop=false`

I have one xaml page where there are multiple UI elements are there, and i wanted narrator to pick some UI element and ignore other. So with below code you can, see that I have four Grid Row Definition the last UI element is rendered on screen as Grid.RowSpan=4 and other UI elements also got intialized just for performance reason, but it won't be visible intially untill the last element Visibility will be set to Collapsed.
What i want when that "UserControlView1" control is rendered narrator should not pick other UI element, but once that is gone then narrator should start picking those UI element.
I have tried IsTabStop=false but not sure why it is not working.
<Page
xmlns:mvvm="using:Prism.Windows.Mvvm"
mvvm:ViewModelLocator.AutoWireViewModel="True"
// some random namespaces declaration
Loaded="PageLoaded">
<Grid>
<Grid.ColumnDefinitions>
// some Grid Column definition
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
// "4" Grid Row definition...
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ctl:UserControlView2
x:Name="UserControlView2"
Grid.Row="1"
Grid.ColumnSpan="2"
IsTabStop="False"/>
<ctl:UserControlView3
x:Name="UserControlView2"
Grid.Row="2"
Grid.Column="0"
IsTabStop="False" --> I have set IsTabStop to false />
<ctl:UserControlView4
x:Name="UserControlView3"
Grid.Row="3"
Grid.Column="0"
IsTabStop="False" --> I have set IsTabStop to false />
<ctl:UserControlView1
d:Visibility="Collapsed"
x:Name="UserControlView1"
x:Load="{x:Bind ViewModel.UserControlView1}"
Grid.Row="0"
Grid.RowSpan="4" // as it span to four rows the reason being its gets render at top of the screen and other UI element will be there beneath it.
Grid.ColumnSpan="2"
TabIndex="0"/>
</Grid>
</Page>

How to prevent Visual Studio XAML Designer from changing Grid size definitions?

I have a Grid defined in XAML like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
<RowDefinition Height="30" />
<RowDefinition Height="2*" />
<RowDefinition Height="30" />
<RowDefinition Height="4*" />
<RowDefinition Height="30" />
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="5" />
</Grid>
If you want to modify the grid by adding/removing rows/columns, you may have to update the Grid.Row/Grid.Column attached properties for many of the grid's children (e. g. when deleting the first two rows, the StackPanel needs to be changed from Grid.Row="5" to Grid.Row="3").
This can become cumbersome if the grid has many children already. Therefore, when modifying an already populated grid at design time, I'm using the visual side of the XAML Designer, because that automatically updates the attached properties of the grid's contents accordingly.
For adding, this works perfectly fine:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
<RowDefinition Height="30" />
<RowDefinition Height="80" /><!-- inserted, simply adjust height as needed -->
<RowDefinition Height="2*" />
<RowDefinition Height="30" />
<RowDefinition Height="4*" />
<RowDefinition Height="30" />
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="6" /><!-- updated -->
</Grid>
For deleting however, it also updates any RowDefinition/ColumnDefinition that has a dynamic size definition (* unit). For example, after deleting the first two rows, I'm left with something like this:
<Grid>
<Grid.RowDefinitions>
<!-- first two removed -->
<RowDefinition Height="30" />
<RowDefinition Height="59*" /><!-- was 2* -->
<RowDefinition Height="30" />
<RowDefinition Height="117*" /><!-- was 4* -->
<RowDefinition Height="30" />
<RowDefinition Height="59*" /><!-- was 2* -->
<RowDefinition Height="29*" /><!-- was implicit 1* -->
</Grid.RowDefinitions>
<StackPanel Grid.Row="3" /><!-- updated -->
</Grid>
Ideally, I want to get the following result:
<Grid>
<Grid.RowDefinitions>
<!-- first two removed, others unchanged -->
<RowDefinition Height="30" />
<RowDefinition Height="2*" />
<RowDefinition Height="30" />
<RowDefinition Height="4*" />
<RowDefinition Height="30" />
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="3" /><!-- updated -->
</Grid>
Right now, I always have to remember to copy the definitions I want to keep before deleting rows or columns in the Visual Designer, so I can paste the copied definition over the mess that got created. But that doesn't even work unless you're only deleting at the edges.
Is there an option to tell the XAML Designer to not pseudo-optimize the size definitions?
I tried things like holding Shift or Control while clicking the "Delete row" menu item, and I looked into the (very few) XAML Designer settings that VS offers, but so far to no avail.
I have Visual Studio 2019 Professional.

Not let Scroll View Appear Larger when made Larger But Instead Make the Overflow Text Appear if you Scroll More, Xamarin

Here is the code I have so far in XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding EquationString}" />
<Entry Grid.Row="1" x:Name="entry" Placeholder="Put Answer Here" />
<Button Grid.Row="2" x:Name="btnCheck" Text="Check Answer"/>
<Label Grid.Row="3" Text="{Binding CheckMessageString}"/>
<BoxView Grid.Row="4" Color="Black" HeightRequest="1" HorizontalOptions="FillAndExpand"/>
<Grid Grid.Row="5" BackgroundColor="White">
<skia:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"
BackgroundColor="White"/>
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
<BoxView Grid.Row="6" Color="Black" HeightRequest="1" HorizontalOptions="FillAndExpand"/>
<Grid Grid.Row="7">
<Button Grid.Column="0" x:Name="btnClear" Text="Clear"/>
<Button Grid.Column="1" x:Name="btnAnalyze" Text="Analyze"/>
</Grid>
<ScrollView Grid.Row="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding ResultString}"/>
<Label Grid.Row="1" Text= "{Binding WorkString}"/>
</Grid>
</ScrollView>
</Grid>
Here is what the view originally looks like
When I press the button Analyze the Text WorkString changes be 4 \n. However I do not want the size of the drawing canvas to change.
Instead what I want to happen is that the size of everything stays the same as before I pressed the button except that the overflow text is now scrollable. In which you have to scroll in order to see that text. Can you guys please assist me with how to do this? Thank you.
If you want fix size on scrollview ,just hard code the last height of RowDefinition, do not use Auto .
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/> //this line
</Grid.RowDefinitions>

Xamarin.Forms: how to center a multine label in a Row?

I try to vertically center a multiline Label that contains a text that can be displayed on 1 or 2 lines.
For the moment, I'm not able to get the expected rendering...
I can have the multiline label that automatically extends but it is top aligned and not centered:
This is the attached XAML:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="0" />
</Grid.RowDefinitions>
<local:MultiLineLabel
Grid.Row="0"
Grid.Column="1"
BackgroundColor="Orange"
Text="{ Binding encart_titre }"
VerticalTextAlignment="Center"
LineBreakMode="TailTruncation"
Lines="2"
...
/>
I can also center the label, but in this case it doesn't auto extends:
This is the attached XAML:
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="0" />
</Grid.RowDefinitions>
<local:MultiLineLabel
Grid.Row="0"
Grid.Column="1"
BackgroundColor="Orange"
Text="{ Binding encart_titre }"
VerticalTextAlignment="Center"
LineBreakMode="TailTruncation"
Lines="2"
VerticalOptions="FillAndExpand"
...
/>
Would you have any explanation? I also tried to add StackLayound around the Label, but this didn't change anything...
The first choice for centering a control would be to use VerticalOptions="CenterAndExpand", have you tried that instead of VerticalOptions="FillAndExpand"? Here's more information about the LayoutOptions in Xamarin.Forms.
So, this would be the correct way to center vertically:
<local:MultiLineLabel
Grid.Row="0"
Grid.Column="1"
BackgroundColor="Orange"
Text="{ Binding encart_titre }"
VerticalTextAlignment="Center"
LineBreakMode="TailTruncation"
Lines="2"
VerticalOptions="CenterAndExpand" <!-- This one here -->
...
/>

How to change grid rows and columns on view change in XAML

I have created 3 x 4 Grid in XAML in Landscape view mode. Means 3 rows and 4 columns. Now on view change to portrait i want to make it 4 x 3 means 4 rows and 3 columns. How to do it.
Plz help me to do it.
Thank you in advance...
I am not really sure as to what you are meaning by how to do it, but to define new grid rows and columns would be:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
This creates a 4x3 grid panel where the widths and heights could be changed to a predetermined size or a *. If this isn't what you are looking for let me know.
Finally i solve it using code behind.
I made two grids one with 3 * 4 and one with 4 * 3
and on size_changed event of page identify the applicationViewstate and show hide the required grid