I know that you can set the row height with a "*" in XAML this way:
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
but the same expression in C# returns an error:
new RowDefinition { Height = new GridLength("*", GridUnitType.Auto) },
So my question is how to set the row height of a grid to a "*" in C#?
var grid = new Grid ();
grid.RowDefinitions.Add (new RowDefinition { Height = GridLength.Auto });
grid.RowDefinitions.Add (new RowDefinition { Height = new GridLength (1, GridUnitType.Star) });
var stacklayout1 = new StackLayout { HeightRequest = 100, BackgroundColor = Color.Red };
var stacklayout2 = new StackLayout { BackgroundColor = Color.Blue };
Grid.SetRow (stacklayout2, 1);
grid.Children.Add (stacklayout1);
grid.Children.Add (stacklayout2);
MainPage = new ContentPage { Content = grid };
Related
I have a project. I have a table. ( Made from grid ) And i have a entry/Textbox. I need make like customer will write number to entry ( Lets call that number "n" ). Then i need add n row inside of my table made from grid. How can i do that ?
Its my codes for make grid table.
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Absolute)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Star)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Absolute)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Star)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Absolute)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Star)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Absolute)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Star)
});
gr.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Absolute)
});
gr.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Absolute)
});
gr.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Star)
});
gr.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Absolute)
});
gr.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Star)
});
gr.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Absolute)
});
var backgroundbox = new BoxView
{
Color = System.Drawing.Color.FromArgb(-32513)
};
gr.Children.Add(backgroundbox, 0, 1);
Grid.SetColumnSpan(backgroundbox, 5);
var ustyatay = new BoxView { Color = System.Drawing.Color.Gray };
gr.Children.Add(ustyatay, 0, 0);
Grid.SetColumnSpan(ustyatay, 5);
var yatay2 = new BoxView { Color = System.Drawing.Color.Gray };
gr.Children.Add(yatay2, 0, 2);
Grid.SetColumnSpan(yatay2, 5);
var yatay3 = new BoxView { Color = Xamarin.Forms.Color.Gray };
gr.Children.Add(yatay3, 0, 4);
Grid.SetColumnSpan(yatay3, 5);
var yatay4 = new BoxView { Color = Xamarin.Forms.Color.Gray };
gr.Children.Add(yatay4, 0, 6);
Grid.SetColumnSpan(yatay4, 5);
var soldik = new BoxView { Color = System.Drawing.Color.Gray };
gr.Children.Add(soldik, 0, 0);
Grid.SetRowSpan(soldik, 7);
var ortadik = new BoxView { Color = Xamarin.Forms.Color.Gray };
gr.Children.Add(ortadik, 2, 0);
Grid.SetRowSpan(ortadik, 7);
var sagdik = new BoxView { Color = System.Drawing.Color.Gray };
gr.Children.Add(sagdik, 4, 0);
Grid.SetRowSpan(sagdik, 7);
gr.Children.Add(new Label
{
Text = "Customer Name",
FontAttributes = FontAttributes.Bold,
TextColor = System.Drawing.Color.Yellow,
FontSize = 16,
Padding=new Thickness(10,10)
}, 1, 1); ;
gr.Children.Add(new Label
{
Text = "T.Type Name",
FontAttributes = FontAttributes.Bold,
TextColor= Xamarin.Forms.Color.Yellow,
FontSize=16,
Padding = new Thickness(10, 10)
}, 3, 1);
I made lines as grid column,row too. I think i made it wrong. When i add n row i need change rowspan too. Idk how can i make that project. Can you guys help me please ? I need learn : How can i add rows with entry , how can i add boxview and rowspan for new row (For make line) ? Thanks for help guys!
That photo for what should i do with my hand drawing : https://prnt.sc/10jxdhn
I can slove the problem by using Data binding.
First, edit your .xaml file like this:
<Entry Text="{Binding N}"></Entry>
<Button Text="Create" Command ="{Binding CreateCommand}"></Button>
<ListView ItemsSource="{Binding Rows}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding}"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Next create a ViewModel, I call it Page1ViewModel.cs.
In .xaml.cs file, add the binding context to Page1ViewModel in the constructor
BindingContext = new Page1ViewModel();
In Page1ViewModel.cs:
class Page1ViewModel : INotifyPropertyChanged
{
private int n;
private List<string> rows;
public List<string> Rows
{
get => rows;
set
{
rows = value;
OnPropertyChanged();
}
}
public int N
{
get => n;
set
{
n = value;
OnPropertyChanged();
}
}
public Command CreateCommand { get; }
public Page1ViewModel()
{
Rows = new List<string>();
CreateCommand = new Command(Create);
}
private void Create()
{
List <string> tmp = new List<string>();
for (int i = 0; i < n; i++)
{
tmp.Add("Row" + i);
}
Rows = tmp;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
Good luck!
I am currently using the package ZXing.Net.Mobile for Xamarin Forms.
I want content on the top of the screen and at the bottom of the screen and I want the scanner to be somewhere in the middle.
If I specify the height of the scanner, it stretches it making it ugly and not nice to have (because the scanner is meant to be used for full screen?).
I want to have some content on the top of the screen with a dynamic height, then I want the scanner with height 150-200, then I want some content to be shown on the rest of the screen.
I was looking into ZXingDefaultOverlay but I could not get it to work as I wanted.
Anyone has an idea, example or an answer that can help me?
Following is the sample code where I have used Grid
for showing content on top and bottom of the screen and middle screen contains scanner.
public ZXingDefaultOverlay()
{
BindingContext = this;
RowSpacing = 0;
VerticalOptions = LayoutOptions.FillAndExpand;
HorizontalOptions = LayoutOptions.FillAndExpand;
RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
RowDefinitions.Add(new RowDefinition { Height = new GridLength(2, GridUnitType.Star) });
RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
Children.Add(new BoxView
{
VerticalOptions = LayoutOptions.Fill,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.Transparent,
Opacity = 0.7,
}, 0, 0);
Children.Add(new BoxView
{
VerticalOptions = LayoutOptions.Fill,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.Transparent,
Opacity = 0.7,
}, 0, 2);
StackLayout ImageLabelContainer = new StackLayout();
Image imgBox = new Image();
imgBox.Source = "scan_qr.png";
imgBox.VerticalOptions = LayoutOptions.Fill;
imgBox.HorizontalOptions = LayoutOptions.FillAndExpand;
ImageLabelContainer.Children.Add(imgBox);
Label lblSuccess = new Label();
lblSuccess.Margin = new Thickness(0, 7, 0, 0);
lblSuccess.HorizontalTextAlignment = TextAlignment.Center;
lblSuccess.TextColor = Color.Green;
lblSuccess.AutomationId = "zxingDefaultOverlay_BottomTextLabel";
lblSuccess.SetBinding(Label.TextProperty, new Binding(nameof(BottomText)));
ImageLabelContainer.Children.Add(lblSuccess);
Children.Add(ImageLabelContainer, 0, 1);
}
Here you can set height of the rows as per your requirement.
I would like to know how to put a stacklayout into a grid case of xamarin forms and repeat tha pattern.
I decleare in my xaml my grid and the stacklayout.
<Grid x:Name="MyGrid" RowSpacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout x:Name="MyLayout">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</Grid>
Then in my c# i wannt to create
var test = new List<Product>
{
new Product() {Desc = "DESC", Brand= "HelloWorld", Price= "30", Uri = "UriToPicture" },
new Product() {Desc = "DESC2", Brand= "HelloWorld2", Price= "30", Uri = "UriToPicture" }
};
Image PicProd = new Image { Aspect = Aspect.AspectFit };
PicProd.Source = FileImageSource.FromUri(new Uri(test[0].Uri));
Label Name= new Label { Text = test[0].Marque.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
Label Desc = new Label { Text = test[0].Desc.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
Label Price = new Label { Text = test[0].Prix.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
MyLayout.Children.Add(PicProd);
MyLayout.Children.Add(Name);
MyLayout.Children.Add(Desc);
MyLayout.Children.Add(Price);
MyGrid.Children.Add(MyLayout, 0, 0);
MyGrid.Children.Add(MyLayout, 0, 1);
Content = MyGrid;
So I have two stacklayout elements that i want to display on two colomns(side by side) but i don't succed to display them correctly
You can set the Grid.Row and Grid.Column on elements to position them inside the grid. These are 0-based indexers. So in your case you could set the StackLayout as follows:
<StackLayout x:Name="MyLayout" Grid.Row="0" Grid.Column="0">
And in the next you could put:
<StackLayout x:Name="MyLayout" Grid.Row="0" Grid.Column="1">
UPDATE:
You cannot add the same instance of a control to a page twice, which is why only one of your items is showing up. You should instantiate 2 actual instances of your StackLayout. Remove the StackLayout from your XAML and declare it in code-behind. Then create 2 separate label instances and add those to the appropriate StackLayout. It should look something like this:
var test = new List<Product>
{
new Product() {Text1 = "DESC", Text2= "HelloWorld" },
new Product() {Text1 = "DESC2", Text2= "HelloWorld2" }
};
MyGrid.BackgroundColor = Color.Yellow;
var Name = new Label { Text = test[0].Text1.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
var Desc = new Label { Text = test[0].Text2.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
var MyLayout = new StackLayout();
MyLayout.BackgroundColor = Color.Red;
MyLayout.Children.Add(Name);
MyLayout.Children.Add(Desc);
MyGrid.Children.Add(MyLayout, 0, 0);
var Name2 = new Label { Text = test[0].Text1.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
var Desc2 = new Label { Text = test[0].Text2.ToString(), TextColor = Color.Black, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
var MyLayout2 = new StackLayout();
MyLayout2.BackgroundColor = Color.Blue;
MyLayout2.Children.Add(Name2);
MyLayout2.Children.Add(Desc2);
MyGrid.Children.Add(MyLayout2, 1, 0);
Another thing to keep in mind, the parameters for the Children.Add call want the column as the first parameter and then the row. Additionally you could use this extension method to simplify the process of adding children with spans etc.
public static class GridExtension
{
public static void AddChild(this Grid grid, View view, int row, int column, int rowspan = 1, int columnspan = 1)
{
if (row < 0) throw new ArgumentOutOfRangeException(nameof(row));
if (column < 0) throw new ArgumentOutOfRangeException(nameof(column));
if (rowspan <= 0) throw new ArgumentOutOfRangeException(nameof(rowspan));
if (columnspan <= 0) throw new ArgumentOutOfRangeException(nameof(columnspan));
if (view == null) throw new ArgumentNullException(nameof(view));
Grid.SetRow((BindableObject)view, row);
Grid.SetRowSpan((BindableObject)view, rowspan);
Grid.SetColumn((BindableObject)view, column);
Grid.SetColumnSpan((BindableObject)view, columnspan);
grid.Children.Add(view);
}
}
So I have two Stacklayout elements that i want to display on two colomns(side by side) but i don't succed to display them correctly
The problem is that you don't have two Stacklayout elements. Instead, you have one single instance that you pass two times to the grid using Add method.
If you want a second Stacklayout side by side, first create a new instance of a Stacklayout either in code or in XAML:
<StackLayout x:Name="MySecondLayout">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
And pass it to your grid using Add method:
//... Populate "MySecondLayout" as you did for "MyLayout"
// Add your two layouts to the grid
MyGrid.Children.Add(MyLayout, 0, 0);
MyGrid.Children.Add(MySecondLayout, 0, 1);
If you want to use the exact same Stacklayout twice side by side, you must create two different instances of a Stacklayout.
In my app I am trying to create a grid layout dynamically but not getting expected output:
Below is the code that I tried:
Grid LayoutGrid = new Grid();
//Created Two Columns
ColumnDefinition gridCol1 = new ColumnDefinition();
ColumnDefinition gridCol2 = new ColumnDefinition();
LayoutGrid.ColumnDefinitions.Add(gridCol1);
LayoutGrid.ColumnDefinitions.Add(gridCol2);
Grid Col1Grid = new Grid();
//Create Two Rows
RowDefinition gridRow1 = new RowDefinition();
RowDefinition gridRow2 = new RowDefinition();
Col1Grid.RowDefinitions.Add(gridRow1);
Col1Grid.RowDefinitions.Add(gridRow2);
Grid.SetColumn(Col1Grid, 1);
return LayoutGrid;
The layout I am trying to create is like this:
I added some colors to be easier to understand
private Grid CreateGrid()
{
var LayoutGrid = new Grid { Background = new SolidColorBrush(Colors.Yellow) };
//Created Two Columns
LayoutGrid.ColumnDefinitions.Add(new ColumnDefinition());
LayoutGrid.ColumnDefinitions.Add(new ColumnDefinition());
//Created Two Rows
LayoutGrid.RowDefinitions.Add(new RowDefinition());
LayoutGrid.RowDefinitions.Add(new RowDefinition());
// region 1 - vertical left
var stack1 = new StackPanel {
Background = new SolidColorBrush(Colors.Red)
};
Grid.SetColumn(stack1, 0);
Grid.SetRowSpan(stack1, 2);
LayoutGrid.Children.Add(stack1);
// region 2 - top right
var stack2 = new StackPanel
{
Background = new SolidColorBrush(Colors.Green)
};
Grid.SetColumn(stack2, 1);
LayoutGrid.Children.Add(stack2);
// region 3 - bottom right
var stack3 = new StackPanel
{
Background = new SolidColorBrush(Colors.Blue)
};
Grid.SetColumn(stack3, 1);
Grid.SetRow(stack3, 1);
LayoutGrid.Children.Add(stack3);
return LayoutGrid;
}
Xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Background="Red" Grid.RowSpan="2"></StackPanel>
<StackPanel Background="Blue" Grid.Column="1"></StackPanel>
<StackPanel Background="Green" Grid.Column="1" Grid.Row="1"></StackPanel>
</Grid>
I have two separate Silverlight usercontrols containing grids and i want these to share a set of columndefinitions. The columndefinitions must be created dynamically. How can i do this?
You can just add them in code if that is sufficient:
private void CreateColumnDefinitions(Grid grid)
{
grid.ColumnDefinitions.Add(
new ColumnDefinition() { Width = new GridLength(10, GridUnitType.Star) });
grid.ColumnDefinitions.Add(
new ColumnDefinition() { Width = new GridLength(5, GridUnitType.Star) });
grid.ColumnDefinitions.Add(
new ColumnDefinition() { Width = new GridLength(5, GridUnitType.Star) });
}