MyCustomPage.xaml is not loading webView in xamarin.Forms portable - xaml

I am beginner in xamarin.forms portable, i am working on xamainr.forms portable project, there i am facing issue. I have a .xaml page in my portable project and i am navigating to this .xaml page from App.cs using following line of code.
var ep = new CustomWebViewPage(dbPath);
var MainEv = new NavigationPage(ep);
Here in CustomWebViewPage i am using WebView in following way to load Url but after successful execution above lines emulator does not load webView. I don't know why it is happening.
I am pasting code of CustomWebViewPage as following.
CustomWebViewPage.xaml.cs
using XamarinDbokReader.SQLite_AppSample;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.IO;
namespace MyDummyProject
{
public partial class CustomWebViewPage : ContentPage
{
public string dbPath = "";
public CustomWebViewPage(string folderPath)
{
this.dbPath = folderPath;
HttpHelperClass helperClass = new HttpHelperClass();
InitializeComponent();
var webView = new WebView();
UrlWebViewSource urlWebViewSource = new UrlWebViewSource()
{
Url = UrlsList.FindUrl("ProEportalLoginPage") + UrlsList.ApiKeys(AppMode.ProductionMode.ToString())
};
webView.Source = urlWebViewSource;
webView.Navigated += (s, e) =>
{
if (e.Url.StartsWith("http://userInfo/?"))
{
string token = "";
try
{
string value_string = Uri.UnescapeDataString(e.Url.ToString());
token = value_string.Split('=')[1];
if (!string.IsNullOrEmpty(token))
{
string path = Path.Combine(dbPath.ToString(), "dBookStore.db3");
helperClass.SaveUserInformation(token, path);
}
}
catch (Exception ss)
{
}
}
};
wvEportalPage = webView;
}
public CustomWebViewPage()
{
}
}
}
CustomWebViewPage.xaml
<?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="XamarinDbokReader.EportalPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
<WebView x:Name="wvEportalPage"></WebView>
</ContentPage>
App.cs
public App(bool isSqliteDbExist, string sPath)
{
isDbExist = isSqliteDbExist;
dbPath = sPath;
if (isDbExist)
{
if (isLoggedIn)
{
NavigationPage navPage = new NavigationPage(new BooksView());
App.Current.MainPage = navPage;
}
else
{
var tdlx = new CustomWebViewPage(dbPath);
var MainNave = new NavigationPage(tdlx);
}
}
else
{
//When cursor is coming from MainActivity then following line executes. And then OnStart() method executes.
ssd.CreateTablesInDb();
isDbExist = true;
}
}
protected override void OnStart()
{
if (isDbExist)
{
if (isLoggedIn)
{
NavigationPage navPage = new NavigationPage(new BooksView());
App.Current.MainPage = navPage;
}
else
{
var ep = new CustomWebViewPage(dbPath);
var MainEv = new NavigationPage(ep);
}
}
}
MainActivity
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
var documents = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var bookCoverFolder = Path.Combine(documents, "BooksCover");
var booksCollection = Path.Combine(documents, "Books");
var bookResource = Path.Combine(documents, "Resource");
if(!Directory.Exists(bookCoverFolder))
Directory.CreateDirectory(bookCoverFolder);
if (!Directory.Exists(booksCollection))
Directory.CreateDirectory(booksCollection);
if(!Directory.Exists(bookResource))
Directory.CreateDirectory(bookResource);
SQLite_Android androidDb = new SQLite_Android();
if (androidDb.IsExist())
{
LoadApplication(new App(true, androidDb.dbStorePath));
}
else
{
LoadApplication(new App(false, androidDb.dbStorePath));
}
}

The WebView probably isn't getting any Width or Height.
Try setting the VerticalOptions and HorizontalOptions properties to FillAndExpand.
So like this:
<?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="XamarinDbokReader.EportalPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
<WebView x:Name="wvEportalPage" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"></WebView>
</ContentPage>
If that doesn't seem to work try wrapping it in a Grid.

Thank you for awesome sugessions, but i found my mistake in code.I did a very small mistake in App.cs After setting navigation page i am not setting NavigationPage to MainPage. It should as below.
var tdlx = new CustomWebViewPage(dbPath);
var MainNave = new NavigationPage(tdlx);
MainPage = MainNave;
it worked perfectly. I knew about MainPage but i have not written due to some other regions but ultimately it is working.

You must define Width and Height to Xamarin WebView.

Related

How to prevent hard line feed in XAML Editor.Text?

I've searched the Web for a solution but could not find one. I have a construct like the following:
<Editor IsReadOnly="True" >
<Editor.Text>
This is a lot of text.
So much text that I want to break it onto two or more lines in my XAML.
</Editor.Text>
</Editor>
The problem is that Xamarin keeps that line feed between text. and So as a hard line feed in the Editor. Is there any way to prevent that and have all the text flow as though it was specified on one line? It's not the end of the world -- I can live with one long line of XAML text, but it is inconvenient.
Thanks.
You could process the Text content to remove \n and remove excess spaces.
Here is a sample for Android (using CustomRenderer).The similar method for iOS.
in your Android project:
[assembly: ExportRenderer(typeof(Editor), typeof(AndroidEditorRenderer))]
namespace xxxx
{
class AndroidEditorRenderer:EditorRenderer
{
public AndroidEditorRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
var str = Control.Text.Replace("\n", "", StringComparison.OrdinalIgnoreCase);
string[] ss = str.Split(' ');
StringBuilder stringBuilder = new StringBuilder();
foreach (var item in ss)
{
if (!string.IsNullOrEmpty(item))
{
stringBuilder.Append(item+" ");
}
}
string content = stringBuilder.ToString().Substring(0,stringBuilder.Length-1);
Control.Text = content;
}
}
}
Update,do this in your page constructor.
public partial class YourPage: ContentPage
{
public YourPage
{
InitializeComponent();
refill();
}
private void refill()
{
var str2 = editor.Text.Replace("\n", "");
string[] ss = str2.Split(' ');
StringBuilder stringBuilder = new StringBuilder();
foreach (var item in ss)
{
if (!string.IsNullOrEmpty(item))
{
stringBuilder.Append(item + " ");
}
}
string content = stringBuilder.ToString().Substring(0, stringBuilder.Length - 1);
editor.Text = content;
}
}

how to convert WebView into IRandomAccessStream in UWP?

What i have Tried is?
My Xaml code :
<Grid x:Name="MyGrid">
<Button x:Name="but" Content="Click" Click="but_Click"></Button>
</Grid>
My C# code:
private async void but_Click(object sender, RoutedEventArgs e)
{
WebView x = new WebView();
x.Width = 100; x.Height = 100;
InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
await x.CapturePreviewToStreamAsync(ms);
}
when I try to convert Webview to Stream.It throws an error like this.
I don't why this was happening .Can Anyone suggest me , How to convert webview to IRandomAccessstream?
The problem is the WebView has not rendered into xaml visual tree. we need to insert WebView into Page content before calling CapturePreviewToStreamAsync method.
private WebView x;
public MainPage()
{
this.InitializeComponent();
x = new WebView();
x.Height = 100; x.Width = 100;
RootGrid.Children.Add(x);
}
private async void bookmarkBtn_Click(object sender, RoutedEventArgs e)
{
InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
await x.CapturePreviewToStreamAsync(ms);
}

Issues when saving files to OneDrive on Windows 10 Mobile

I’m working on an application where you should be able to open and save files, similar to “Notepad”. It’s a universal application that should work both on computers and mobiles.
The application works fine on computers. It also works fine on mobile if I save or open files locally or on Dropbox.
But if I open a file on OneDrive (via the file picker), and then try to save an exception is thrown: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
If I select “Save as” on OneDrive it works. But every time I select Save after this a new instance of the file is created (I get “file 1”, “file 2”, “file 3” and so on).
I have only tested this on my phone. I might have a bug on my application, but since it works on DropBox I don’t think so. Is this a known issue with OneDrive? Or might I just have some local issues? I’m using Windows 10 Mobile 10.10586.420 and OneDrive 17.11.
Here is some code to illustrate the problem:
<Page
x:Class="BasicEditor.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BasicEditor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="40">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Open"
Click="OpenButton_Click" />
<Button Content="Save"
Click="SaveButton_Click" />
<Button Content="Save as"
Click="SaveAsButton_Click" />
</StackPanel>
<TextBox Grid.Row="1" x:Name="TextEditor"
TextWrapping="Wrap" />
</Grid>
</Page>
using System;
using System.Collections.Generic;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace BasicEditor
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
string MruToken;
private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.List;
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".txt");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
try
{
string fileContent = await FileIO.ReadTextAsync(file);
TextEditor.Text = fileContent;
string token = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "");
MruToken = token;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write($"Open-Error: {ex.Message}");
var dialog = new MessageDialog($"Open-Error: {ex.Message}");
await dialog.ShowAsync();
}
}
}
private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
try
{
var file = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(MruToken);
string fileContent = await FileIO.ReadTextAsync(file);
await FileIO.WriteTextAsync(file, TextEditor.Text);
var dialog = new MessageDialog($"Saved successfully");
await dialog.ShowAsync();
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write($"Save-Error: {ex.Message}");
var dialog = new MessageDialog($"Save-Error: {ex.Message}");
await dialog.ShowAsync();
}
}
private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });
savePicker.SuggestedFileName = "New Document";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
try
{
await FileIO.WriteTextAsync(file, TextEditor.Text);
string token = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "");
MruToken = token;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write($"SaveAs-Error: {ex.Message}");
var dialog = new MessageDialog($"SaveAs-Error: {ex.Message}");
await dialog.ShowAsync();
}
}
}
}
}
A beta of my app is available here: https://www.microsoft.com/store/apps/9NBLGGH3MFM3
Another app with exactly the behavior when OneDrive is used is NotepadX.

Custom CommandBar to PickerFlyout

By default PickerFlyout has commandbar that has done and cancel buttons. Is it possible to disable done button programmatically? If not is there any way to add custom command bar and replace default one?
With the help of the answer given i tried to write custom picker from PickerFlyoutBase. But now i'm not able to add content to flyout in xaml. Giving me error saying custompicker doesnt support direct content
<Button>
<Button.Flyout>
<local:custompicker>
<TextBlock Margin="20" FontSize="30" Text="MyPickerFlyout Test" />
</local:custompicker>
</Button.Flyout>
</Button
public class custompicker:PickerFlyoutBase
{
private AppBar OriginalAppBar;
private CommandBar MyCommandBar;
private Page CurrentPage;
public custompicker()
{
var cancelButton = new AppBarButton();
cancelButton.Icon = new SymbolIcon(Symbol.Cancel);
cancelButton.Label = "Cancel";
cancelButton.Click += (s, e) =>
{
this.Hide();
};
MyCommandBar = new CommandBar();
MyCommandBar.PrimaryCommands.Add(cancelButton);
this.Closed += MyPickerFlyout_Closed;
this.Opening += MyPickerFlyout_Opening;
this.Placement = Windows.UI.Xaml.Controls.Primitives.FlyoutPlacementMode.Full;
}
private void MyPickerFlyout_Opening(object sender, object e)
{
CurrentPage = (Windows.UI.Xaml.Window.Current.Content as Frame).Content as Page;
if (CurrentPage != null)
{
OriginalAppBar = CurrentPage.BottomAppBar;
CurrentPage.BottomAppBar = MyCommandBar;
}
}
private void MyPickerFlyout_Closed(object sender, object e)
{
if (CurrentPage != null)
{
CurrentPage.BottomAppBar = OriginalAppBar;
}
}
}
PickerFlyout class has a ConfirmationButtonsVisible property, we can use this property to disable both "Done" and "Cancel" button.
But there is no way to disable only "Done" button. We have to implement a custom "PickerFlyout". Following is a simple custom "PickerFlyout" based on Flyout, you can refer to it to implement your own.
public class MyPickerFlyout : Flyout
{
private AppBar OriginalAppBar;
private CommandBar MyCommandBar;
private Page CurrentPage;
public MyPickerFlyout()
{
var cancelButton = new AppBarButton();
cancelButton.Icon = new SymbolIcon(Symbol.Cancel);
cancelButton.Label = "Cancel";
cancelButton.Click += (s, e) =>
{
this.Hide();
};
MyCommandBar = new CommandBar();
MyCommandBar.PrimaryCommands.Add(cancelButton);
this.Closed += MyPickerFlyout_Closed;
this.Opening += MyPickerFlyout_Opening;
this.Placement = Windows.UI.Xaml.Controls.Primitives.FlyoutPlacementMode.Full;
}
private void MyPickerFlyout_Opening(object sender, object e)
{
CurrentPage = (Windows.UI.Xaml.Window.Current.Content as Frame)?.Content as Page;
if (CurrentPage != null)
{
OriginalAppBar = CurrentPage.BottomAppBar;
CurrentPage.BottomAppBar = MyCommandBar;
}
}
private void MyPickerFlyout_Closed(object sender, object e)
{
if (CurrentPage != null)
{
CurrentPage.BottomAppBar = OriginalAppBar;
}
}
}
Then you can use it in XAML like:
<Button Content="Show Picker">
<Button.Flyout>
<local:MyPickerFlyout Closed="PickerFlyout_Closed">
<TextBlock Margin="20" FontSize="30" Text="MyPickerFlyout Test" />
</local:MyPickerFlyout>
</Button.Flyout>
</Button>
And it looks like:

Can I implement file download using MVC4's ApiController?

Using regular Controller I could do it by returning FileResult. The same doesn't seem to work with ApiController. Can it be done? Is it even a right thing to do?
Try this.
[HttpGet]
public HttpResponseMessage Get()
{
var file = HttpContext.Current.Server.MapPath("~/Images/accent.png");
var stream = new FileStream(file, FileMode.Open);
var content = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
};
content.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return content;
}
I have this working thanks to this question.
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
namespace Web.Controllers
{
//usage: /download/report
[RoutePrefix("download")]
public class DownloadController : ApiController
{
[HttpGet("report")]
public HttpResponseMessage Report()
{
using (var service = new Client())
{
var report = service.BuildReport();
return DownloadResponse(report, "Report.csv");
}
}
private static HttpResponseMessage DownloadResponse(string content, string fileName)
{
var downloadContent = new StringContent(content);
var mediaType = new MediaTypeHeaderValue("application/octet-stream");
var disposition= new ContentDispositionHeaderValue("attachment") { FileName = fileName };
downloadContent.Headers.ContentType = mediaType;
downloadContent.Headers.ContentDisposition = disposition;
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = downloadContent
};
return result;
}
}
}