How to remove grid children in a specific RowDefinition? - xamarin.forms

I'm drawing the controls dynamically at run time inside a grid. I want to clear all children under a specific control when the user taps on it. I have this but this only remove the RowDefinitions:
var currentRow = Grid.GetRow((BindableObject)sender);
for (int i = currentRow + 1; i < grdDynamic.RowDefinitions.Count; i++)
{
grdDynamic.RowDefinitions.RemoveAt(i);
}
but I need to clear all the grid children in those RowDefinitions.

This should remove the children in your grid with the tapped row as attribute.
var children = grdDynamic.Children.ToList();
foreach (var child in children.Where(child => Grid.GetRow(child) == row)) {
grdDynamic.Children.Remove(child);
}
It loops over all children in your grid and removes the child if its row equals the tapped row.

Related

QML TreeView collapse section when click different section

I have a QML TreeView which expands / collapses branches upon click (builtin to treeview). However, when I expand one branch, I want other branches at the same depth to collapse. I've gotten as far as the code below which collapses ALL branches when an item is clicked.
How can I collapse ONLY branches which are NOT on the path from root index to the clicked index? (Either in C++ or JS)? So that it behaves like an accordion
In my TreeView:
onClicked: {
console.log(index)
for(var i=0; i < treemodel.rowCount(); i++) {
var nextIndex = treemodel.index(i,0)
if(mytreeview.isExpanded(nextIndex)) {
mytreeview.collapse(nextIndex)
}
}
}

Make table row behave like an accordion

I'm using a table to display assignments. The table row has an initial height value of 300px. When the table is loaded, the table row height is reduced to 50px so that some of the details are hidden and this is done by adding a style.
.hidedetails {
max-height: 50px;
}
To show the hidden details, the user needs to click on the down-arrow. By doing that, the .hidedetails style is removed and the following is added, at the same time the down-arrow changes to an up-arrow.
.showdetails {
min-height: 300px;
}
To hide the details again, the user simply clicks on the up-arrow, which then changes again to the down-arrow. The result is the following:
I would like to know how can I hide the details of the table row that is showing them if I click on the down-arrow of the table row that is not selected. I have tried with JQuery but it won't work.
In case anyone is interested, I was able to achieve what I wanted by adding this to the onClick event of the arrow icon which is a button widget.
var tableRow = widget.parent.parent;
var rows = tableRow.parent.children._values;
if (widget.text === ("keyboard_arrow_down") ) {
for (var i = 0; i < rows.length; i++) {
if (rows[i].name.indexOf('Table2Row') > -1) {
rows[i].styles = ['hidedetails'];
rows[i].descendants.Button3.text = "keyboard_arrow_down";
}
}
tableRow.styles = ['showdetails'];
widget.text = "keyboard_arrow_right";
} else if (widget.text === ("keyboard_arrow_right")){
tableRow.styles = ["hidedetails"];
widget.text = "keyboard_arrow_down";
}

Keeping css attributes in an iterated dart template

I'm working on a Dart project where the user is able to add new custom elements at the click of a button. Each custom element is a div containing a table. The divs are resizeable by the user. My problem is that after a new element is added to the list of elements held by my dart file, the sizes of all the divs are automatically reset. Is there any way to add new elements to the template while keeping the attributes of the old ones the same?
Here is my CSS code that deals with the main divs in my custom element:
#superDivContainer {
border: 2px solid black;
resize: both;
display: inline-block;
}
#tableContainer {
height: 125px;
overflow: scroll;
}
Thanks in advance for the help!
When you change the backing list, the template reiterates, destroying all the old elements and recreating them from scratch, so all user resize information is lost.
When you add a new item to the list, you can store all the sizing information of the old elements and then after the item is added set the new elements size:
// Stores size information
List<List> sizes = [];
void add() {
// Store the old sizes
sizes.clear();
ElementList divs = queryAll(".superDivContainer");
for(int i = 0; i < divs.toList().length; i++) {
Element div = divs[i];
sizes.add([div.style.width, div.style.height]);
}
// Add the new item
yourList.add("new");
// Set the sizes of the new elements
Timer timer = new Timer(new Duration(milliseconds: 1), () {
divs = queryAll(".superDivContainer");
for(int i = 0; i < divs.toList().length && i < sizes.length; i++) {
Element div = divs[i];
div.style.width = sizes[i][0];
div.style.height = sizes[i][1];
}
});
}
Two notes:
I changed superDivContainer to be a class instead of an id since it seems that you are applying it to multiple elements; you will need to change your CSS reflect that
The 1 millisecond timer gets around the fact that there is a tiny delay until the new elements are added and accessible

dynamic add component

I want to dynamically add component in Container like Canvas(TileList constraints each child has the same size, GridList is poor in performance), for example
<mx:Canvas id="myHolder" width="600" height="550">
</mx:Canvas>
<mx:Button label="Add Button" click="addButton()"/>
when I click the button, I hope add a component(whatever the component is, and maybe each component has different size), and if the total width of all added child is greater than myHolder, I hope the new child can begin in new line, and stretch the height of myHolder at the same time.(layout with custom code is better)
On Canvas you have complete freedom to lay components anywhere using their x and y properties, so there's a lot of ways to skin this cat. Since you need rows, one of the methods may be (not tested):
//inside of your Canvas-based component
private function updateChildrenPositions():void
{
var rowY:Number = 0;
var rowWidth:Number = 0;
var rowHeight:Number = 0;
for (var i:int = 0, total:int = numChildren; i < total; i++)
{
var child:DisplayObject = getChildAt(i);
if (rowWidth + child.width > width)
{
//child will cause overflow, start next row
rowY += rowHeight;
rowWidth = 0;
rowHeight = 0;
}
rowWidth += child.width;
child.x = rowWidth;
child.y = rowY;
if (child.height > rowHeight) rowHeight = child.height; //accumulating max height
}
height = rowY + rowHeight;
}
This assumes Canvas has fixed width and set height depending on layout. You can add paddings and gaps later, it's a good exercise :)
To get the functionality you want, I wouldn't use an HBox. As alxx suggested, a TileList would be a better fit in this situation.
Here are some examples using a TileList to get you started:
http://blog.flexexamples.com/category/halo/tilelist/
http://learn.adobe.com/wiki/display/Flex/TileList

Get size of autosized control?

I have a situation where I have several listbox controls on the same asp.net page. They are currently autosized to keep data from truncating. However, I would like to be able to determine the width of the largest listbox and then alter the size of the other listboxes to be the same.
The question is... How can I access the size of the listboxes? Or Can I?
Yes you can...
//This is a <div> that wraps around your listboxes
var wrapperDiv = document.getElementById('listboxWrapper');
//Get all <select> elements within the <div>
var sels = wrapperDiv.getElementsByTagName('SELECT');
//An array to store the width values
var widths = new Array();
//Load the array
for(var i = 0, l = sels.length; i < l; i++)
widths[i] = sels[i].offsetWidth;
//Get the max width
var maxW = Math.max(widths);
//Set the max width to all the list boxes
for(var sel in sels)
sels[sel].style.width = maxW;
for the best results, consider using a javascript framework, using jquery:
var width = 0;
//get the largest width
$("select").each(function() {
if ($(this).width() > width) {
width = $(this).width();
}
});
//make them all the same width
$("select").css("width", width);

Resources