I have a webview in one of my page and I want to add a stacklayout from the top then the webview. But Webview take whole screen and the stacklayout never get shown. I want to hide default navigation bar and create my own one. I still couldn't test for the apple side
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:other="clr-namespace:CustApp.CusApp.Dushan.Other"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
EnableBackButtonOverride="True"
x:Class="CustApp.Views.GeneralPayments.MotorPayments.hnb.HNBmotorPayment">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" VerticalOptions="Start" HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10,5,10,5">
<Image HorizontalOptions="StartAndExpand" Source="pdfDown.png"/>
<Label HorizontalOptions="CenterAndExpand" Text="ALL"/>
<Image HorizontalOptions="EndAndExpand" Source="pdfDown.png"/>
</StackLayout>
<WebView Grid.Row="1" x:Name="webView"
HorizontalOptions="CenterAndExpand"
Navigating="webView_Navigating"
Navigated="MywebView_Navigated"/>
</Grid>
</ContentPage.Content>
</ContentPage>
Code behind
protected override void OnAppearing()
{
base.OnAppearing();
NavigationPage.SetHasNavigationBar(this, false);
if (isFirstRun)
{
jsonOutput = JsonConvert.SerializeObject(payData);
//var htmlSource = new HtmlWebViewSource();
var urlSource = new UrlWebViewSource();
string url = DependencyService.Get<IBaseUrl>().Get();
TempUrl = Path.Combine(url, "xamarinhtmlmotor.html");
urlSource.Url = TempUrl;
webView.Source = urlSource;
isFirstRun = false;
Content = webView;
}
}
The cause is you set the Content = webView in code behind which means the the whole content is webview and those code in the Xaml will be overwritten.
Solution:
Remove Content = webView; and try again.
Related
I created a simple program with MAUI to load 2 images, specified as Embedded Resources.
This is the MainPage:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Surprise.MainPage">
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="550"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<VerticalStackLayout x:Name="ImageContainer"
Grid.Row="0"
HeightRequest="500"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Grid Grid.Row="1"
HorizontalOptions="Center"
HeightRequest="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Text="Image1"
Grid.Column="0"
Clicked="OnImage1ButtonClicked" />
<Button Text="Image2"
Grid.Column="2"
Clicked="OnImage2ButtonClicked" />
</Grid>
</Grid>
</ScrollView>
</ContentPage>
and this is its code behind:
public partial class MainPage : ContentPage
{
private readonly Image _image1;
private readonly Image _image2;
public MainPage()
{
InitializeComponent();
_image1 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image1.jpeg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
_image2 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image2.jpg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
}
private void OnImage1ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image1);
}
private void OnImage2ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image2);
}
}
On Windows it works correctly.
On Android sometimes the images are loaded in wrong order or even the same image is loaded when I press each button.
Is it a MAUI bug or I'm missing something?
Thanks in advance.
Well, there are some changes that were made with Maui projects, we now have Maui-specific build actions that you can use to specify to your project/solution what the type of a certain file is.
In your Scenario, you should use the MauiImage build action then just uses the name of the file as shown here: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/image#load-a-local-image should be enough to fix your issue
I have this xaml class:
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
HeightRequest="130"
WidthRequest="90"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="InteriorCircle.Pages.MainMenu.CV_PinStyle">
<ContentView.Content>
<StackLayout BackgroundColor="Transparent">
<Frame
HeightRequest="130"
WidthRequest="90"
VerticalOptions="Start"
HasShadow="False"
HorizontalOptions="Start"
BackgroundColor="#565656"
Padding="0"
CornerRadius="25"
IsClippedToBounds="true">
<StackLayout Padding="5">
<Grid VerticalOptions="Center" Margin="10,10,0,0" HorizontalOptions="Center">
<Image x:Name="img_pic"
Margin="3,0,0,0"
HorizontalOptions="Center"
VerticalOptions="Center">
<Image.Clip>
<EllipseGeometry
Center="27,27"
RadiusX="27"
RadiusY="27"/>
</Image.Clip>
</Image>
<Ellipse Stroke="#60CED3"
StrokeThickness="6"
WidthRequest="60"
HeightRequest="60"
HorizontalOptions="Start" />
</Grid>
<Label
Margin="0,0,0,0"
x:Name="label_title"
TextColor="White"
LineBreakMode="TailTruncation"
FontFamily="JakartaReg"
VerticalOptions="Start"
FontSize="12"
HorizontalOptions="Center"/>
<Label
x:Name="label_price"
TextColor="White"
FontFamily="JakartaBold"
VerticalOptions="Start"
FontSize="10"
HorizontalOptions="Center"/>
</StackLayout>
</Frame>
</StackLayout>
</ContentView.Content>
</ContentView>
I retrieve content from another class (event) and set it to the properties from here:
private async Task SetContent(EventType events)
{
InitializeComponent();
byte[] bt = Converters.StringToByteArray(events.eventPictureThumb);
label_title.Text = events.name;
label_price.Text = Converters.GetDecimalPriceFromCents(events.priceInCents) + " €";
Device.BeginInvokeOnMainThread(() =>
{
var source = Converters.ReturnImageSourceFromString(Converters.ByteArrayToString(bt));
img_pic.Source = source;
});
}
However, this does not work sometimes on Android, on iOS not at all.
When I set an image directly in xaml, it is always displayed. On iOS, when the image comes from code, it is never displayed. On Android, it is displayed most of the times, but fails sometimes. When multiple objects load into the view the old ones lose their images.
I am adding the view like so:
var startPin = BitmapDescriptorFactory.FromView(new CV_PinStyle(currentEvent));
Pin pin = new Pin
{
Label = currentEvent.name,
Tag = currentEvent.tblEventID+Constants.DELIMITER+currentEvent.userID,
Icon = startPin,
Type = PinType.Place,
Position = position
};
gMap?.Pins?.Add(pin);
So I am doing somethign wrong here,
can you help me?
I am getting issue to open sliding drawer from right to left for
xamarin android . but below code working for show sliding
drawer from left to right. if any property of MasterDetailPage to
open sliding from right to left
please share your views with me. Here Sliding Drawer open from left to right but i want to open from right to left for Xamarin
Android
Any idea regarding this. please share your idea's.
We are also using MenuRootPage for add items in Sliding Drawer :
Code for items view:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
>
<ContentPage.Content>
<StackLayout BackgroundColor="{StaticResource ToolbarStatusBackgroundColor}" Orientation="Vertical" Spacing="20">
<StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{mm:Command SliderClose}" />
</StackLayout.GestureRecognizers>
<Image Source="menu.png" HorizontalOptions="Start" Margin="10,40,0,0" />
</StackLayout>
<BoxView HorizontalOptions="EndAndExpand" HeightRequest="1" WidthRequest="1000" Color="{StaticResource SeparatorColor}" />
<Label Text="My account" Style="{StaticResource ToolbarStatusDescriptionLabel}" Margin="10" >
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{mm:Command SliderClose}" />
</Label.GestureRecognizers>
</Label>
<BoxView HorizontalOptions="EndAndExpand" HeightRequest="1" WidthRequest="1000" Color="{StaticResource SeparatorColor}" />
<Label Text="Settings" Style="{StaticResource ToolbarStatusDescriptionLabel}" Margin="10">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{mm:Command SliderClose}" />
</Label.GestureRecognizers>
</Label>
<BoxView HorizontalOptions="EndAndExpand" HeightRequest="1" WidthRequest="1000" Color="{StaticResource SeparatorColor}" />
<Label Text="Logout" Style="{StaticResource ToolbarStatusDescriptionLabel}" HorizontalTextAlignment="Center" VerticalOptions="EndAndExpand" Margin="10">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{mm:Command Logout}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ContentPage.Content>
</ContentPage>
In MenuRootPage .xaml file we are declare master page only UI section
In MenuRootPage .cs file: here we are inherit MasterDetailPage properties
Using code:
Root page in MenuRootPage .xaml file:
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Ansible.Vektor.App.Shared.Views.MenuRootPage" >
</MasterDetailPage>
Root MenuRootPage .cs file:
public partial class MenuRootPage : MasterDetailPage
{
public MenuRootPage ()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
}
}
App.xaml.cs:
var menuPage = new MenuPages() { BindingContext = MenuPagesViewModel };
NavigationPage = new NavigationPage(new MainView() {
BindingContext = MainViewModel });
MenuRootPage = new MenuRootPage();
MenuRootPage.Master = menuPage;
MenuRootPage.Detail = NavigationPage;
MenuIsGestureEnabled = false;
MainPage = MenuRootPage;
Here Sliding Drawer open from left to right but i want to open from right to left for Xamarin Android
Any idea regarding this. please share your idea's.
Make custom render for Master Detail Page in Android.
public class MyMasterDetailPageRenderer : MasterDetailPageRenderer
{
protected override void OnElementChanged(VisualElement oldElement, VisualElement newElement)
{
base.OnElementChanged(oldElement, newElement);
var fieldInfo = GetType().BaseType.GetField("_masterLayout", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
var _masterLayout = (ViewGroup)fieldInfo.GetValue(this);
var lp = new DrawerLayout.LayoutParams(_masterLayout.LayoutParameters);
lp.Width = 300;
lp.Gravity = (int)GravityFlags.Right;
_masterLayout.LayoutParameters = lp;
}
}
I'm facing a pretty weird problem trying to catch taps on certain images on my screen first here is my xaml code for a popup window implemented as a View :
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NumbersRaceXamarin.YesNoPopupMessages">
<ContentView.Content>
<RelativeLayout HeightRequest="190" WidthRequest="280">
<Image x:Name="bg" Source="compbar_01.png" Aspect="Fill" HeightRequest="190" WidthRequest="330" Opacity="0.9" InputTransparent ="true"/>
<StackLayout WidthRequest="280" Spacing="0" RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width , Factor=0.1,Constant=0}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height , Factor=0.02,Constant=0}">
<Label x:Name="message" FontSize="15"></Label>
<StackLayout WidthRequest="70" HeightRequest="30" Orientation="Horizontal" HorizontalOptions="Center">
<RelativeLayout WidthRequest="30" HeightRequest="30" VerticalOptions="Center">
<Image x:Name="minus" Source="startbottuns_01.png" Aspect="Fill" HeightRequest="30" WidthRequest="30"/>
<Label x:Name="minusTB" Text="-" FontSize="16" HeightRequest="30" WidthRequest="30" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</RelativeLayout>
<Label x:Name="qtyTB" Text="1" FontSize="8" HeightRequest="30" WidthRequest="30" BackgroundColor="White" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
<RelativeLayout WidthRequest="30" HeightRequest="30" VerticalOptions="Center">
<Image x:Name="plus" Source="startbottuns_01.png" Aspect="Fill" HeightRequest="30" WidthRequest="30" IsEnabled="true"/>
<Label x:Name="plusTB" Text="+" FontSize="16" HeightRequest="30" WidthRequest="30" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</RelativeLayout>
</StackLayout>
<StackLayout x:Name="coinAmountSeg" HeightRequest="40" WidthRequest="90" Orientation="Horizontal" HorizontalOptions="Center" IsVisible="true">
<Label x:Name="coinsAmountTB" Text="1200" HeightRequest="35" WidthRequest="40" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
<Image x:Name="coinsPackIM" Source="coins_01.png" HeightRequest="35" WidthRequest="25"/>
</StackLayout>
<StackLayout x:Name="yesNoBtSeg" HeightRequest="32" WidthRequest="150" Orientation="Horizontal" HorizontalOptions="Center" IsVisible="true">
<RelativeLayout HorizontalOptions="Center" >
<Image x:Name="yesBt" x:Uid="yesBt" Source="startbottuns_01.png" Aspect="Fill" HeightRequest="32" WidthRequest="80"></Image>
<Label x:Name="yesTB" Text="OK" FontSize="20" HeightRequest="32" TextColor="Yellow" WidthRequest="80" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</RelativeLayout >
<RelativeLayout HorizontalOptions="Center" >
<Image x:Name="noBt" x:Uid="noBt" Source="startbottuns_01.png" Aspect="Fill" HeightRequest="32" WidthRequest="80"></Image>
<Label x:Name="noTB" Text="CANCEL" FontSize="20" HeightRequest="32" TextColor="Yellow" WidthRequest="80" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</RelativeLayout>
</StackLayout>
</StackLayout>
</RelativeLayout>
</ContentView.Content>
</ContentView>
and here is how I try to catch the events from plus and minus ok and cancel images:
var minusTap = new TapGestureRecognizer();
var plusTap = new TapGestureRecognizer();
var okTap = new TapGestureRecognizer();
var cancelTap = new TapGestureRecognizer();
minusTap.Tapped += minusBtn_Click;
plusTap.Tapped += plusBtn_Click;
okTap.Tapped += okBtn_Click;
cancelTap.Tapped += cancelBtn_Click;
noBt.GestureRecognizers.Add(cancelTap);
plus.GestureRecognizers.Add(plusTap);
minus.GestureRecognizers.Add(minusTap);
yesBt.GestureRecognizers.Add(okTap);
private void okBtn_Click(object sender, EventArgs e)
{
tcs.SetResult(1);
}
private void cancelBtn_Click(object sender, EventArgs e)
{
tcs.SetResult(0);
}
private void minusBtn_Click(object sender, EventArgs e)
{
if (int.Parse(qtyTB.Text) > 1)
{
coinsAmountTB.Text = "" + (int.Parse(coinsAmountTB.Text) - itemCost);
qtyTB.Text = (int.Parse(qtyTB.Text) - 1) + "";
}
}
private void plusBtn_Click(object sender, EventArgs e)
{
if (int.Parse(qtyTB.Text) < max)
{
coinsAmountTB.Text = "" + (int.Parse(coinsAmountTB.Text) + itemCost);
qtyTB.Text = (int.Parse(qtyTB.Text) + 1) + "";
}
}
the problem is really strange the tap events work fine on the ok cancel and minus buttons but won't fire when taping the plus image for some reason.
I thought something was overlapping and "stealing" the taps on the plus button but I can't find anything like that .
BTW I'm trying this on android not trying on other devices.
anyone have any idea how and why this happens?
Ok so I found the silly problem thought I'd share my solution in case anyone encounter the same issue.
the problem was that the stacklayout that contains the buttons had less width than the elements it contained so the last element the plus in this case was out of the stacklayout bounds and that caused it to not get the tap gesture
<StackLayout WidthRequest="70" HeightRequest="30" Orientation="Horizontal" HorizontalOptions="Center">
<RelativeLayout WidthRequest="30" HeightRequest="30" VerticalOptions="Center">
this line here I just changed the WidthRequest to 100 instead of 70 because it has 3 elements 30 width each .
Hope this helps someone
I had the same problem, also caused by the parent element having less size than the tap-enabled child.
In my case, I had an absolute layout (Inner) inside another absolute layout (Outer). I was then adding the tap-enabled child elements programmatically to Inner in the code-behind.
<AbsoluteLayout x:Name="Outer">
<AbsoluteLayout x:Name="Inner" />
</AbsoluteLayout>
Because Inner had no AbsoluteLayout.LayoutBounds specified, it seems the interaction cycle ignored the children. This was not obvious to me because the child elements were visible.
This worked:
<AbsoluteLayout x:Name="Outer">
<AbsoluteLayout x:Name="Inner"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All" />
</AbsoluteLayout>
However, I ended up putting my tap target elements in the Outer container, which also resolved the issue, as Outer is enclosed by a ContentPage.
why isn't the WebView showing ? I have tried FillAndExpand and CenterAndExpand , but it still not working!
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MyApp.Views;assembly=MyApp"
x:Class="MyApp.Pages.Main">
<StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="Start">
<!-- top controls -->
</StackLayout>
<StackLayout x:Name="WebViewLayout" VerticalOptions="CenterAndExpand">
<WebView Source="https://www.google.com/" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="End">
<views:AdMobView WidthRequest="400" HeightRequest="50" />
</StackLayout>
</StackLayout>
</ContentPage>
Change the Vertical Options of the StackLayout (which holds the WebView) from CenterAndExpand to FillAndExpand and the WebView itself.
I hope this helps. :)
<StackLayout x:Name="WebViewLayout" VerticalOptions="FillAndExpand">
<WebView Source="https://www.google.com/" VerticalOptions = "FillAndExpand"/>
</StackLayout>
I would suggest taking the WebView out of the parent StackLayout and the change the outer most StackLayout to a Grid.
That being said, I think that might help solve the issue without doing that:
public override void OnAppearing() {
SizeChanged += (sender, e) => {
WebViewItem.WidthRequest = Width;
WebViewItem.HeightRequest = 200; //Or what ever
}
OnSizeChanged(null, null); //Make it run at least once
}
I can't say exactly why but setting the VerticalOptions on the stack layout seemed to solve it for me. The following results in the web view being drawn:
var webView = new WebView();
webView.Source = "https://www.xamarin.com";
webView.MinimumWidthRequest = 200;
webView.MinimumHeightRequest = 200;
webView.HorizontalOptions = LayoutOptions.FillAndExpand;
webView.VerticalOptions = LayoutOptions.FillAndExpand;
var stackLayout = new StackLayout;
this.Content = stackLayout;
stackLayout.Children.Add(webView);
stackLayout.HorizontalOptions = LayoutOptions.FillAndExpand;
stackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
I admit the layout behavior for StackLayout is pretty confusing.