I have a function in xamarin and I want to use the value of this return function as a column in my view. So here is my function:
public int setColumn()
{
int column = 0;
int product_number = 0;
foreach (Product product in AllProducts)
{
product_number++;
if(product_number % 3 == 0)
{
column++;
product_number = 0;
}
}
return column;
}
So this function apparently set the column number for my view. So I want to show 3 columns in one row and I am counting via looping my list. So here is my view:
<Grid HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Button
Text="{Binding Name}"
Grid.Column="setColumn"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="Black"
BackgroundColor="#EEF2FF"
Command="{Binding AddProductCommand}"
CommandParameter="{Binding .}"
/>
</Grid>
So here I want to call my function --> Grid.Column="setColumn" and set the column number.
Related
I want to insert user control to itemscontrol in wpf using prism.
The user control is printed, but I don't know how to do data binding.
ViewA.xaml
<Grid>
<ItemsControl ItemsSource="{Binding People}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Grid.Row="1" Margin="10"
prism:RegionManager.RegionName="PersonDetailsRegion"
prism:RegionManager.RegionContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
ViewAViewModel.cs
private ObservableCollection<Person> _people;
public ObservableCollection<Person> People
{
get { return _people; }
set { SetProperty(ref _people, value); }
}
public ViewAViewModel()
{
CreatePeople();
}
private void CreatePeople()
{
var people = new ObservableCollection<Person>();
for (int i = 0; i < 10; i++)
{
people.Add(new Person()
{
FirstName = String.Format("First {0}", i),
LastName = String.Format("Last {0}", i),
Age = i
});
}
People = people;
}
insert a menu item into viewA.
MenuItem.xaml
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- First Name -->
<TextBlock Text="First Name:" Margin="5" />
<TextBlock Grid.Column="1" Margin="5" Text="{Binding FirstName}" />
<!-- Last Name -->
<TextBlock Grid.Row="1" Text="Last Name:" Margin="5" />
<TextBlock Grid.Row="1" Grid.Column="1" Margin="5" Text="{Binding LastName}" />
<!-- Age -->
<TextBlock Grid.Row="2" Text="Age:" Margin="5"/>
<TextBlock Grid.Row="2" Grid.Column="1" Margin="5" Text="{Binding Age}"/>
</Grid>
![The current situation is as follows.][1]
https://i.stack.imgur.com/1VBai.png
How to do data binding? please help me
thanks you
This won't work like this. You have to create the region on the "outside", i.e. on the ItemsControl and remove the ItemsSource binding. Then navigate multiple times to the items control-region to populate it.
<ItemsControl prism:RegionManager.RegionName="PersonDetailsRegion"/>
Alternatively, keep the binding of ItemsSource and remove the ContentControl inside and put DataTemplates somewhere for your views. Then populate it by putting the view models into the items source.
<DataTemplate DataType={x:Type Person}"><PersonView /></DataTemplate>
...
<ItemsControl ItemsSource="{Binding People}"/>
Personally, I'd prefer the second variant most of the time, because you evade the added complexity of packing your persons' information in navigation parameters and getting them back, not to speak of the much simpler PersonViewModel...
How to display a three column layout usingHome.xaml , the below is still displaying as single column, I have added teh row definition and column definition with in the <Grid></Grid>, Please advise
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="soccerapp.Home" BackgroundColor="White" Title="Home">
<ContentPage.Content>
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="Player1" BackgroundColor="#f4d144"/>
<Label Grid.Row="1" Text="Player2" BackgroundColor="#ed4edd"/>
<Label Grid.Row="2" Text="Player3" BackgroundColor="#44ce9e"/>
<Label Grid.Row="3" Text="Player4" BackgroundColor="#44ce9e"/>
<Label x:Name="HomeLabel" Text="Home Page is here" TextColor="White"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" FontSize="Medium"></Label>
</Grid>
</ContentPage.Content>
</ContentPage>
Please find the below screen shot ( grid displaying in single column, this is not I want )
....I would like to display the Grid as per below screenshot:
first, you have only defined two columns, not three. Second, you are placing all of your labels in the first column
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Use Grid.Column to specify column -->
<Label Grid.Row="0" Grid.Column="0" Text="Player1" BackgroundColor="#f4d144"/>
<Label Grid.Row="0" Grid.Column="1" Text="Player2" BackgroundColor="#ed4edd"/>
<Label Grid.Row="0" Grid.Column="2" Text="Player3" BackgroundColor="#44ce9e"/>
</Grid>
I have the following grid layout set up in my XAML page.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BoxView BackgroundColor="Red" Grid.Row="0" Grid.Column="0">
<BoxView.GestureRecognizers>
<PanGestureRecognizer PanUpdated="PanGestureRecognizer_OnPanUpdated"/>
</BoxView.GestureRecognizers>
</BoxView>
<BoxView BackgroundColor="Green" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" />
<BoxView BackgroundColor="Red" Grid.Row="0" Grid.Column="3" />
<BoxView BackgroundColor="Blue" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />
<BoxView BackgroundColor="Purple" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2"/>
<BoxView BackgroundColor="Aqua" Grid.Row="2" Grid.Column="0" />
<BoxView BackgroundColor="Fuchsia" Grid.Row="2" Grid.Column="1" />
<BoxView BackgroundColor="GreenYellow" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2">
</BoxView>
</Grid>
I want to add a drag and drop functionality on each box view. The idea is I should be able to drag each box view and drop it on another box view having the same column span. Can someone please advise me on how to do this ? Please help.
Unfortunately, there is no built-in drag and drop functionality in Xamarin.Forms just yet. You can still implement it yourself using PanGestureRecognizer.
You can add gesture recognizer to your view, for example Label, like this:
<Label>
<Label.GestureRecognizers>
<PanGestureRecognizer PanUpdated="PanGestureRecognizer_OnPanUpdated" />
</Label.GestureRecognizers>
</Label>
Now in the PanUpdated event handler you can use TranslationX and TranslationY to move a view around.
private double _startTranslationX, _startTranslationY
private void PanGestureRecognizer_OnPanUpdated(object sender,
PanUpdatedEventArgs e)
{
var box = (BoxView) sender;
if (e.StatusType == GestureStatus.Started)
{
_startTranslationX = box.TranslationX;
_startTranslationY = box.TranslationY;
}
else if (e.StatusType == GestureStatus.Running)
{
box.TranslationX = _startTranslationX + e.TotalX;
box.TranslationY = _startTranslationY + e.TotalY;
}
else if (e.StatusType == GestureStatus.Completed)
{
box.TranslationX = _startTranslationX + e.TotalX;
box.TranslationY = _startTranslationY + e.TotalY;
//handle drop here (depending on your requirements)
}
}
To actually implement a drop functionality you will have to manually test where the object is currently located and if dropping is allowed there.
My goal is to have a listview with a resizeable icon on the left, and 3 lines of text in the other column. Here is the template I've tested so far:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Margin="0,0" Padding="0,0" ColumnSpacing="0" RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="85*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0" Source="{Binding sImageSource}" Aspect="AspectFit" />
<StackLayout Grid.Row="0" Grid.Column="1" Orientation="Vertical" Margin="0" Padding="0" Spacing="0">
<Label Text="{Binding sDisplayName}" FontSize="Medium" LineBreakMode="TailTruncation" YAlign="Center" TextColor="Black"/>
<Label Text="{Binding sFileSize}" FontSize="Micro" TextColor="Gray" YAlign="Center"/>
<Label Text="{Binding sFileDate}" FontSize="Micro" TextColor="Gray" YAlign="Center"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
If the ColumnDefinition Width="15*" is changed to "25*" I just get a wider column, and the picture is not changed in height (As I though it would).
Actually what I want is that RowDefinition Height="ColumnDefinition Width="15*"", so the both resize linear based on the parameter set as width.
Does anyone have tips regarding this?
PS: I have also tested HasUnevenRows=True, but that sets the height of each cell too high.
Edit:
Another variation has been tested:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" x:Name="MyImageGrid"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition BindingContext="{x:Reference MyImageGrid}" Height="{Binding Path=ActualWidth}"/>
</Grid.RowDefinitions>
But that did not work either. Have anyone done such a solution before?
I sort-of solved this little nut, but it was more complicated than it should be.
Here is the solution if anyone wonders.
In your contentpage-csfile, you have to add an property to store the value needed
public partial class YourPage : ContentPage
{
//....
public class RowHeight : INotifyPropertyChanged
{
private int nInternalHeight;
public event PropertyChangedEventHandler PropertyChanged;
public int Height
{
get { return nInternalHeight; }
set
{
nInternalHeight = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Height"));
}
}
}
//....
public RowHeight oRowHeight { get; set; }
//....
public YourPage()
{
oRowHeight = new RowHeight();
}
//....
protected override void OnAppearing()
{
base.OnAppearing(); //Width is -1 if set right away in YourPage() creation
oRowHeight.Height = (int)(App.Current.MainPage.Width * 0.15);
}
//....
Now in the XAML part of the code.
Our object oRowHeight.Height needs to be bound to our RowDefinition Height property.
The ListView also must have the following criterias:
1. HasUnevenRows = True
2. Page has to have a name for the reference
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourApp.Views.YourPage"
x:Name="YourPageName">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding OtherItems}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Margin="0,0" Padding="0,0" ColumnSpacing="0" RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="85*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding Source={x:Reference YourPageName}, Path=BindingContext.oRowHeight.Height}" />
</Grid.RowDefinitions>
<!-- Like the rest of XAML above -->
I am developing a windows phone app. I need to create a 3X3 grid like structure. I want the border to be invisible initially. When a user touches a border, it should become visible. Kindly give me some guidance how to get started . I am new to windows phone framework. Also, can it be done in silverlight or I need xna ?
Silverlight is good. Add a grid with 3 columns and 3rows and columns
<Grid Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
then add border elements to every row*column, something like this:
public MainPage()
{
InitializeComponent();
var borders = new Border[3,3];
var handler = new EventHandler<GestureEventArgs>(MainPage_Tap);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
borders[i,j] = new Border()
{
BorderThickness = new Thickness(4),
Opacity = 0,
BorderBrush = new SolidColorBrush(Colors.White)
};
borders[i, j].Tap += handler;
Grid.SetRow(borders[i,j], i);
Grid.SetColumn(borders[i,j], j);
grid.Children.Add(borders[i, j]);
}
}
void MainPage_Tap(object sender, GestureEventArgs e)
{
var snd = sender as Border;
snd.Opacity = 1;
}
I used an array of border so you can easily manipulate them later, but that's not really required.
EDIT: If you'd like border just around the whole grid, do the same thing with the tap event, but set the border in XAML like this
<Grid Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Grid.RowSpan="3" Grid.ColumnSpan="3" Opacity="0" Tap="handler" />
</Grid>