popup message box in xamarin.form - xamarin

What I am trying to do is similar to DisplayAlert, popup a display page that contains image, content and a small close button at top right. The display page shouldn't cover the whole phone but just around 80% of the phone UI, background remain as parent page.
I am trying to play around with PushModalAsync and PopModalAsync, however with no luck. The output is not what I expected.
Basically, I have a listview, whenever item is selected from screen it will call for popUpMethod:
list.ItemSelected += MyMethod;
inside MyMethod i will call popUpPage
async void MyMethod(object sender, SelectedItemChangedEventArgs e){
Content = await PopUpPage();
}
and this is my PopUpPage method
private async Task<StackLayout> PopUpPage()
{
StackLayout objPopUp = new StackLayout() { HeightRequest = 100, WidthRequest= 100, VerticalOptions = LayoutOptions.CenterAndExpand};
Label lblMessage = new Label();
lblMessage.Text = "Welcome";
objPopUp.Children.Add(lblMessage);
return objPopUp;
}
I am trying to set the height and width inside my popup page. However, it is still covering the whole screen which is not what I want. let me know if any top up information is needed, thank you.
P/S : i designed it in xamarin.Form(portable)

You can create a custom pop-up to accomplish this in Xamarin.Forms
Here is a custom ContentView that I created. It uses a BoxView to give the appearance of fading the background, and uses a Frame to add a shadow to the pop-up.
I also use animations to make the custom pop-up appear as if it is springing off of the screen!
Sample App
The code for this sample app is available on Github:
https://github.com/brminnick/InvestmentDataSampleApp
Code Snippet
public class WelcomeView : ContentView
{
readonly BoxView _backgroundOverlayBoxView;
readonly Frame _overlayFrame;
readonly StackLayout _textAndButtonStack;
readonly RelativeLayout _relativeLayout;
public WelcomeView()
{
const string titleText = "Welcome";
const string bodyText = "Enjoy InvestmentDataSampleApp";
const string okButtonText = "Ok, thanks!";
var whiteWith75Opacity = new Color(255, 255, 255, 0.75);
_backgroundOverlayBoxView = new BoxView
{
BackgroundColor = whiteWith75Opacity
};
_backgroundOverlayBoxView.Opacity = 0;
_overlayFrame = new Frame
{
HasShadow = true,
BackgroundColor = Color.White
};
_overlayFrame.Scale = 0;
var titleLabel = new Label
{
FontAttributes = FontAttributes.Bold,
Text = titleText,
HorizontalTextAlignment = TextAlignment.Center
};
var bodyLabel = new Label
{
Text = bodyText,
HorizontalTextAlignment = TextAlignment.Center
};
var blackWith75PercentOpacity = new Color(0, 0, 0, 0.75);
var okButton = new Button
{
BackgroundColor = blackWith75PercentOpacity,
TextColor = Color.White,
BorderWidth = 1,
BorderColor = blackWith75PercentOpacity,
FontAttributes = FontAttributes.Bold,
Margin = new Thickness(5),
Text = okButtonText
};
okButton.Clicked += (sender, e) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
await this.FadeTo(0);
this.IsVisible = false;
this.InputTransparent = true;
});
}
_textAndButtonStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Spacing = 20,
Children = {
titleLabel,
bodyLabel,
okButton
}
};
_textAndButtonStack.Scale = 0;
_relativeLayout = new RelativeLayout();
Func<RelativeLayout, double> gettextAndButtonStackHeight = (p) => _textAndButtonStack.Measure(_relativeLayout.Width, _relativeLayout.Height).Request.Height;
Func<RelativeLayout, double> gettextAndButtonStackWidth = (p) => _textAndButtonStack.Measure(_relativeLayout.Width, _relativeLayout.Height).Request.Width;
_relativeLayout.Children.Add(_backgroundOverlayBoxView,
Constraint.Constant(-10),
Constraint.Constant(0),
Constraint.RelativeToParent(parent => parent.Width + 20),
Constraint.RelativeToParent(parent => parent.Height)
);
_relativeLayout.Children.Add(_overlayFrame,
Constraint.RelativeToParent(parent => parent.Width / 2 - gettextAndButtonStackWidth(parent) / 2 - 20),
Constraint.RelativeToParent(parent => parent.Height / 2 - gettextAndButtonStackHeight(parent) / 2 - 10),
Constraint.RelativeToParent(parent => gettextAndButtonStackWidth(parent) + 30),
Constraint.RelativeToParent(parent => gettextAndButtonStackHeight(parent) + 30)
);
_relativeLayout.Children.Add(_textAndButtonStack,
Constraint.RelativeToView(_overlayFrame, (parent, view) => view.X + 15),
Constraint.RelativeToView(_overlayFrame, (parent, view) => view.Y + 15)
);
if (Device.OS == TargetPlatform.Android)
{
_overlayFrame.IsVisible = false;
_textAndButtonStack.BackgroundColor = whiteWith90Opacity;
}
Content = _relativeLayout;
}
public void DisplayView()
{
Device.BeginInvokeOnMainThread(async () =>
{
var animationList = new List<Task>
{
_backgroundOverlayBoxView.FadeTo(1,AnimationConstants.WelcomeViewAnimationTime),
_textAndButtonStack.ScaleTo(AnimationConstants.WelcomeViewMaxSize, AnimationConstants.WelcomeViewAnimationTime),
_overlayFrame.ScaleTo(AnimationConstants.WelcomeViewMaxSize,AnimationConstants.WelcomeViewAnimationTime)
};
await Task.WhenAll(animationList);
animationList = new List<Task>
{
_textAndButtonStack.ScaleTo(AnimationConstants.WelcomeViewNormalSize, AnimationConstants.WelcomeViewAnimationTime),
_overlayFrame.ScaleTo(AnimationConstants.WelcomeViewNormalSize, AnimationConstants.WelcomeViewAnimationTime)
};
await Task.WhenAll(animationList);
});
}
}

PushModalAsync will push page over your current page. Instead use same page add one frame in it. configure frame with whatever controls you want.
1. set frame Visibility to false and on ItemSelected make frame visible. OR
2. add frame dynamically on ItemSelected (haven't tried 2nd approach.).

Change your code like as following.
private async Task<StackLayout> PopUpPage () {
StackLayout objPopUp = new StackLayout () {HeightRequest = 0, WidthRequest = 0, VerticalOptions = LayoutOptions.Center, Padding = 10 };
Label lblMessage = new Label ();
lblMessage.Text = "Welcome";
objPopUp.Children.Add (lblMessage);
return objPopUp;
}

You may use the XLabs-PopUp-Control.
With that control, you can show a PopUp from you page where you can define the size without problems. I use it on various pages.
Link how to use it
Link how to install and setup XLabs

Related

how to add button n times on xamarin

First of all i have seen few topics about that but didnt helped i typed thoose in xamarin.
i add a button in that way
Button desk = new Button
{
Text = desknumber.ToString(),
Font = Font.SystemFontOfSize(NamedSize.Large),
BorderWidth = 1,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand
};
so i have to run this command in loop or in a method like that
public void masaekle(int masasayisi)
{
Button desknumber = new Button
{
Text = masasayisi.ToString(),
Font = Font.SystemFontOfSize(NamedSize.Large),
BorderWidth = 1,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand
};
this.Content = new StackLayout
{
Children =
{
desknumber,
}
};
it doesnt work in any variable type so i stuck here i cant give a variable name to the button
every time you assign Content it overwrites what is already there
var sl = new StackLayout();
// some loop conditions
for(;;)
{
var button = new Button { ... };
sl.Children.Add(button);
}
this.Content = sl;

Xamarin - binding to variable in datatemplate

How do I bind a value from my object property to a variable so that I can pass it as an argument/parameter for my method "setFavoriteProduct(id_product, favnumber) which is triggered by my button "choiceButton". I require the property value "id_product".
When I bind it to Label "id_productLabel" then I can see it in the View just fine but I need to use the string value in my "setFavoriteProduct" function.
listView.ItemTemplate = new DataTemplate(() =>
{
Image productImage = new Image();
productImage.SetBinding(Image.SourceProperty, "imageURL");
//productImage.HeightRequest = 60;
productImage.HeightRequest = 120;
//productImage.WidthRequest = 60;
productImage.WidthRequest = 120;
productImage.Aspect = Aspect.AspectFit;
Label nameLabel = new Label();
nameLabel.SetBinding(Label.TextProperty, "name");
Label id_productLabel = new Label();
id_productLabel.SetBinding(Label.TextProperty, "id_product");
id_productLabel.IsVisible = true;
Button choiceButton = new Button();
choiceButton.Text = "Vali";
choiceButton.Clicked += (sender, args) => setFavoriteProduct(
id_product,
favnumber
);
return new ViewCell
{
View = new StackLayout
{
Padding = new Thickness(0, 5),
Orientation = StackOrientation.Horizontal,
Children = { productImage, id_productLabel , nameLabel, choiceButton }
}
};
the simplest way to do this is to get the BindingContext from the sender (button) and then get the property from that
choiceButton.Clicked += (sender, args) => {
var context = (MyClass)((Button)sender).BindingContext;
var id = context.id_product;
setFavoriteProduct(id,favnumber);
};
alternately, you could use the Button's Command and CommandParameter properties instead of the Clicked event

xamarin Forms - Is it possible to get Grid row selection event?

How do i get row id of grid row selection? I want to add row unique id and i want it on tapped or on clicked. please suggest me if anyone have any idea.
I want to do some thing like this, if i click on the row and i get id. with this id i will fetch another records and send user on another page. for this i need unique id of the row.
i have grid like bellow:
Below is the code i use:
public BusList(Common busdata)
{
InitializeComponent();
this.BindingContext = this;
List<BusDetail> Bus = new List<BusDetail>
{
...
new BusDetail("Nita Travel","Mumbai", "Navsari",new DateTime(2017, 3, 9), "10:15 AM", "09:15 AM")
};
Label header = new Label
{
Text = "GridView Demo",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
HorizontalOptions = LayoutOptions.Center
};
var controlGrid = new Grid
{
RowSpacing = 2,
ColumnSpacing = 2,
Margin = new Thickness(5, Device.OnPlatform(5, 0, 0), 5, 5)
};
controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
for (int i = 0; i < Bus.Count(); i++)
{
controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
}
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
Bus = Bus.Where(x => x.FromDest.ToLower().Contains(busdata.FromDest.ToLower()) && x.FromDate == busdata.FromDate).ToList();
controlGrid.Children.Add(new Label { Text = "ID", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 0, 0);
controlGrid.Children.Add(new Label { Text = "Travel Name", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 1, 0);
controlGrid.Children.Add(new Label { Text = "Arr Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 2, 0);
controlGrid.Children.Add(new Label { Text = "Dep Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 3, 0);
for (int i = 0; i < Bus.Count(); i++)
{
var clickableRow = new ContentView();
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, i.ToString());
clickableRow.GestureRecognizers.Add(tapGestureRecognizer);
clickableRow.BindingContext = i.ToString();
controlGrid.Children.Add(clickableRow, 0, i);
Grid.SetColumnSpan(clickableRow, 3);
controlGrid.Children.Add(new Label { Text = Bus[i].TravelName, BindingContext = Bus[i].TravelName, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 1, i + 1);
controlGrid.Children.Add(new Label { Text = Bus[i].ArrivalTime, BindingContext = Bus[i].ArrivalTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 2, i + 1);
controlGrid.Children.Add(new Label { Text = Bus[i].DepartureTime, BindingContext= Bus[i].DepartureTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 3, i + 1);
}
this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);
this.Content = new StackLayout
{
Children =
{
header,
controlGrid
}
};
}
public void RowTappedCommand(string index)
{
var tappedRow = int.Parse(index);
}
You could add a ContentView to each row on the first column and span it across all columns by using the ColumnSpan property. Then you'd handle the taps with a TouchGestureListener. When creating the Command, you'd also include a CommandParameter which contains the index of the row in question.
Outside the constructor, define this:
public ICommand RowTappedCommand { get; private set; }
Then add the following code somewhere after InitializeComponent:
RowTappedCommand = new Command<string>(RowTapped);
Then create the clickable ContentView controls for each row:
var clickableRow = new ContentView {
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
}
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
var binding = new Binding();
binding.Source = i.ToString();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, binding); // This is the index of the row
clickableRow.GestureRecognizers.Add(tapGestureRecognizer);
controlGrid.Children.Add(clickableRow, 0, 0);
Grid.SetColumnSpan(clickableRow,3);
You also need to define the method that matches the name defined in the CommandProperty. If you have a view model defined for the view you need to do it there. Otherwise, you'll need to add the method to your view's code behind file (xaml.cs).
void RowTapped(string index)
{
var tappedRow = int.Parse(index);
// Do something with the value
}
Remember to set the BindingContext correctly so that your command gets called. Here's more information about Commands in Xamarin.Forms:
Update: There were a few mistakes that needed to be fixed.
Command wasn't defined correctly.
The binding for the command property needs to be pointing to a static value
Simplifying Events with Commanding

xamarin screen design from code behind

I am new to xamarin.i am trying to create accordian control in xamarin forms.i had created also.in which at starting level i had put only buttons and label like this
for demo purpose.this is i binded from code behind.like this
var vViewLayout1 = new StackLayout()
{
Children = {
new Label { Text = "Regular Board Meeting",HorizontalOptions=LayoutOptions.Center },
new StackLayout
{
Spacing = 5,
Orientation = StackOrientation.Horizontal,
VerticalOptions= LayoutOptions.Center,
HorizontalOptions= LayoutOptions.End,
Children =
{
new Image { Source = "Chat.png"},
new Button { Text ="Reject",BackgroundColor = Color.Red,TextColor = Color.White},
new Button { Text ="Approve",BackgroundColor = Color.Green,TextColor = Color.White}
}
},
//new Label { Text = "Name : S Ravi Kumar" },
//new Label { Text = "Roles : Father,Trainer,Consultant,Architect" }
}
};
var vFirstAccord = new AccordionSource()
{
HeaderText = "ReportToBoardJune 1,2016",
HeaderTextColor = Color.White,
HeaderBackGroundColor = Color.Red,
ContentItems = vViewLayout1
};
return vResult;
but i want to display data such like this
so ,how can i create this from code behind.and which control i should use for box that i highlighed by red arrow.boxview or any other availble in xamarine like table or anything else.
i just started xamarin.so i dont have any idea about its controls.any suggestion or help is apriciated.thanks in advance.
Based on the comments you're going to use grid, and your question is now essentially How can I make a border round the grid in the code behind file?
There is no specific border property for grid as you've discovered. What I've done a few times is create a simple 3x3 grid, and placed 4 boxviews around the edges:
BoxView border()
{
BoxView res = new BoxView
{
Color = Color.Black,
HeightRequest = 4,
WidthRequest = 4
}
return res;
}
Grid gridWithBorder = new Grid
{
RowDefinitions =
{
new RowDefinition { Height = GridLength.Auto},
new RowDefinition { Height = GridLength.Auto},
new RowDefinition { Height = GridLength.Auto}
},
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Auto },
new ColumnDefinition { Width = GridLength.Auto },
new ColumnDefinition { Width = GridLength.Auto }
}
};
gridWithBorder.Children.Add(border(), 0, 3, 0, 1); //add top border
gridWithBorder.Children.Add(border(), 0, 1, 0, 3); // left border
gridWithBorder.Children.Add(border(), 0, 3, 2, 3); // bottom border
gridWithBorder.Children.Add(border(), 2, 3, 0, 3); // right
After this I then add the rest of the layout to row 1 column 1

Visifire.Charts How to disable vertical lines. WP

Chart is created by code. But I can't disable vertical lines in chart.
It is a code of creating chart:
public void CreateChart() {
CleanChart();
visiChart = new Chart()
{
ToolTipEnabled = true,
Width = 400,
Height = 200,
Padding = new Thickness(0),
Margin = new Thickness(0, 6, 0, -12),
Background = new SolidColorBrush(Colors.White),
};
ChartGrid grid = new ChartGrid()
{
Enabled = false
};
DataSeries dataSeries = new DataSeries();
DataPoint dataPoint;
Axis yAx = new Axis()
{
AxisLabels = new AxisLabels() { Enabled = false },
Grids = new ChartGridCollection() {grid}
};
int i = 0;
var deps = App.CurrentAgreement.Deposits.Deposit.Where(x => x.DepositIliv + x.DepositLink > 0).ToList();
foreach (var dep in deps) {
dataPoint = new DataPoint();
dataPoint.YValue = dep.DepositIliv + dep.DepositLink + dep.UValue + dep.WarrantyValue;
dataPoint.XValue = i;
i++;
dataPoint.LabelText = dataPoint.YValue.Out();
dataPoint.AxisXLabel = DateTime.Parse(dep.DepositDate).ToString("MMM yyyy");
dataPoint.MouseLeftButtonUp += dataPoint_MouseLeftButtonUp;
dataSeries.DataPoints.Add(dataPoint);
}
dataSeries.LabelEnabled = true;
dataSeries.RenderAs = RenderAs.Column;
dataSeries.Color = new SolidColorBrush(Colors.Green);
visiChart.Series.Add(dataSeries);
visiChart.AxesY.Add(yAx);
ChartPlaceHolder.Children.Add(visiChart);
}
But i dont need vertical lines visible. It is a screen of chart.
How i can disable lines??
Help me, please.
You have to disable the Grid lines from AxisX also.
Example:
ChartGrid grid = new ChartGrid()
{
Enabled = false
};
Axis xAx = new Axis();
xAx.Grids.Add(grid);
visiChart.AxesX.Add(xAx);

Resources