How to print Webview on a windows store app - c#

Hey guys i have been trying to print my Webview using the tutorial Jerry Nixon gave on How do I print WebView content in a Windows Store App? and the tutorial from "windows 8 apps with xaml and c#" by Adam Nathan, i have attached the code below from his example:
using System;
using Windows.Graphics.Printing;
using Windows.Graphics.Printing.OptionDetails;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Printing;
namespace Chapter19
{
public sealed partial class MainPage : Page
{
// Supports printing pages, where each page is a UIElement
PrintDocument doc = new PrintDocument();
public MainPage()
{
InitializeComponent();
// Attach handlers to relevant events
doc.GetPreviewPage += OnGetPreviewPage;
doc.AddPages += OnAddPages;
PrintManager printManager = PrintManager.GetForCurrentView();
printManager.PrintTaskRequested += OnPrintTaskRequested;
}
// Prepare the print preview pages
void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
this.doc.SetPreviewPageCount(2, PreviewPageCountType.Final);
if (e.PageNumber == 1)
{
this.doc.SetPreviewPage(1, new Viewbox
{
Child = new Button
{
Content = "PAGE 1!",
Background = new SolidColorBrush(Colors.Red)
}
});
}
else
{
this.doc.SetPreviewPage(2, new Viewbox
{
Child = new Button
{
Content = "PAGE 2!",
Background = new SolidColorBrush(Colors.Red)
}
});
}
}
// Prepare the real pages
void OnAddPages(object sender, AddPagesEventArgs e)
{
this.doc.AddPage(new Viewbox
{
Child = new Button
{
Content = "PAGE 1!",
Background = new SolidColorBrush(Colors.Red)
}
});
this.doc.AddPage(new Viewbox
{
Child = new Button
{
Content = "PAGE 2!",
Background = new SolidColorBrush(Colors.Red)
}
});
this.doc.AddPagesComplete();
}
// Prepare and perform the printing
void OnPrintTaskRequested(PrintManager sender,
PrintTaskRequestedEventArgs args)
{
// This gets invoked as soon as the Devices pane is shown
PrintTask task = args.Request.CreatePrintTask("Document Title",
async (taskArgs) =>
{
// This is invoked on a background thread when the Print
// button is clicked
var deferral = taskArgs.GetDeferral();
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// This must run on the main thread
taskArgs.SetSource(doc.DocumentSource);
deferral.Complete();
});
});
// Show custom options
PrintTaskOptionDetails details =
PrintTaskOptionDetails.GetFromPrintTaskOptions(task.Options);
details.DisplayedOptions.Clear();
details.DisplayedOptions.Add(StandardPrintTaskOptions.MediaSize);
// A custom text option
PrintCustomTextOptionDetails option1 = details.CreateTextOption(
"CustomId1", "Header");
details.DisplayedOptions.Add("CustomId1");
// A custom list option
PrintCustomItemListOptionDetails option2 = details.CreateItemListOption(
"CustomId2", "Contents");
option2.AddItem("customItemId1", "As Seen on Screen");
option2.AddItem("customItemId2", "Summary View");
option2.AddItem("customItemId3", "Full Details");
option2.AddItem("customItemId4", "Multiple Columns");
details.DisplayedOptions.Add("CustomId2");
// Handle options changes
details.OptionChanged += OnOptionChanged;
}
void OnOptionChanged(PrintTaskOptionDetails sender, PrintTaskOptionChangedEventArgs args)
{
// TODO: Handle custom options
}
}
}
the problem i am having is that i am struggling to get "MywebviewPages" that jerry generated onto the
"this.doc.SetPreviewPage"
and
"this.doc.AddPage"
from Nathans example. Due to lack of PDF api's on winRT i am forced to use webview since its the only way to have tables. please help

Related

UWP create new window for each file opened

I'm trying to make an app open a window for each file.
-- Code ---
App.cs:
protected async override void OnFileActivated(FileActivatedEventArgs Args)
{
//Opens Main Page
base.OnFileActivated(Args);
var RF = new Frame();
var MW = new MainPage();
AppWindow appWindow = await AppWindow.TryCreateAsync();
var TB = appWindow.TitleBar;
RF.Navigate(typeof(MainPage), Args);
ElementCompositionPreview.SetAppWindowContent(appWindow, RF);
appWindow.Equals(MW);
Window.Current.Equals(MW);
await appWindow.TryShowAsync();
TB.ButtonHoverBackgroundColor = Colors.White;
TB.ButtonHoverForegroundColor = Colors.Black;
TB.ButtonBackgroundColor = Colors.Transparent;
TB.ButtonPressedBackgroundColor = Colors.WhiteSmoke;
TB.ButtonPressedForegroundColor = Colors.Black;
TB.ButtonInactiveBackgroundColor = Colors.Transparent;
TB.ButtonInactiveForegroundColor = Color.FromArgb(1, 3, 165, 252);
TB.ExtendsContentIntoTitleBar = true;
Window.Current.Activate();
}
MainPage.cs:
protected override async void OnNavigatedTo(NavigationEventArgs EvArgs)
{
//File opened arguments
base.OnNavigatedTo(EvArgs);
var Args = EvArgs.Parameter as IActivatedEventArgs;
var FArgs = Args as FileActivatedEventArgs;
string Value = GetText(REB);
string SecValue = GetText(RTB);
if (Args != null)
{
//Check if the app is opened by file
if (Args.Kind == ActivationKind.File)
{
//Set file content
TXTFile = FArgs.Files[0] as StorageFile;
if (Value == "")
{
var Str = await TXTFile.OpenReadAsync();
ContentDialog ED2 = FileSaveDialog;
ED2.PrimaryButtonClick += ED2_PrimaryButtonClick;
void ED2_PrimaryButtonClick(ContentDialog Sender, ContentDialogButtonClickEventArgs DialogEvArgs)
{
//Save the file if it isn't saved
Save();
}
ED2.SecondaryButtonClick += ED2_SecondaryButtonClick;
void ED2_SecondaryButtonClick(ContentDialog Sender, ContentDialogButtonClickEventArgs DialogEvArgs)
{
//Don't save the file
//Set document content
REB.Document.LoadFromStream(TextSetOptions.FormatRtf, Str);
RTB.Document.LoadFromStream(TextSetOptions.FormatRtf, Str);
Str.Dispose();
}
ED2.CloseButtonClick += ED2_CloseButtonClick;
void ED2_CloseButtonClick(ContentDialog Sender, ContentDialogButtonClickEventArgs DialogEvArgs)
{
//Cancel the action
}
await ED2.ShowAsync();
Str.Dispose();
}
else
{
//Set document content
var Str = await TXTFile.OpenReadAsync();
REB.Document.LoadFromStream(TextSetOptions.FormatRtf, Str);
RTB.Document.LoadFromStream(TextSetOptions.FormatRtf, Str);
Str.Dispose();
}
}
}
else
{
//If there are no arguments, the file, and the RichEditBox should both remain empty
}
}
public string GetText(RichEditBox RichEditor)
{
RichEditor.Document.GetText(TextGetOptions.FormatRtf, out string Text);
var Range = RichEditor.Document.GetRange(0, Text.Length);
Range.GetText(TextGetOptions.FormatRtf, out string Value);
return Value;
}
Note:
the GetText method used is equivalent to RichEditBox.Document.GetText(TextGetOptions.FormatRtf, out string Value);
REB is the main workspace for the user to type in
RTB is the box that is compared with REB to see if the contents are saved or not (if the contents are saved, the GetText method should return their values equal)
Expected behavior:
If the app has a window active with text, the app should open a file on double click in a secondary window. Else, if the text is equal to "", the app should replace it with whatever is in the file.
Actual behavior:
The app overrides the text, crashes, makes windows randomly, or creates black windows that can only be killed with Task Manager or Visual Studio
I'm not sure what is the file type that you are using so I didn't check the text part. But I have to say that the way you are creating a new window is not correct. If you want to open a new window every time when you open a new file, you don't have to call Window.Current.Activate(); every time. I've made a simple demo that you could check.
In App.xaml.cs:
protected async override void OnFileActivated(FileActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// Place the frame in the current Window
Window.Current.Content = rootFrame;
rootFrame.Navigate(typeof(MainPage), args.Files);
Window.Current.Activate();
}
else
{
AppWindow appWindow = await AppWindow.TryCreateAsync();
Frame appWindowContentFrame = new Frame();
appWindowContentFrame.Navigate(typeof(MainPage),args.Files);
ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame);
await appWindow.TryShowAsync();
}
}
When you launch the app for the first time, you should go through the normal launch process. When the app is launched more than onetime, then you could create a new window with AppWindow.
In MainPage.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// this is the file you need
var d = e.Parameter;
}
You could try this code first to make sure that your window is created and shown correctly.

Windows action center toast activation

I'm currently working on a winforms app which after certain action sends a notification to user, when activated(clicked) it opens a link. So I can send the notification, I can open the link with toast.Activated but when banner disappear and gets in to the action center when I click on the notification it doesn't activate. So, I have searched a lot but couldn't find a way to activate the notification on action center.
Here is the code I'm currently using to send notification.
{
public void Toasty()
{
// Get a toast XML template
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText04);
// Fill in the text elements
Windows.Data.Xml.Dom.XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
stringElements[0].AppendChild(toastXml.CreateTextNode("Header"));
stringElements[1].AppendChild(toastXml.CreateTextNode("Message"));
stringElements[2].AppendChild(toastXml.CreateTextNode("From"));
ToastNotification toast = new ToastNotification(toastXml);
toast.Activated += toast_Activated;
//toast.SuppressPopup = true;
ToastNotificationManager.CreateToastNotifier("App").Show(toast);
}
async void toast_Activated(ToastNotification sender, object args)
{
await Launcher.LaunchUriAsync(new Uri("http://www.google.com"));
}
}
You don't need raw xml for this, get this nuget package :
Microsoft.Toolkit.Uwp.Notifications, then use the ToastContentBuilder to build a toast notification, it's easier and cleaner:
// Construct the visuals of the toast (using Notifications library)
ToastContent toastContent = new ToastContentBuilder()
.AddToastActivationInfo("action=viewConversation&conversationId=5", ToastActivationType.Foreground)
.AddText("Hello world!")
.GetToastContent();
// And create the toast notification
var toast = new ToastNotification(toastContent.GetXml());
// And then show it
DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
Now for the activation part:
//Another way of creating a notification
public void CreateAndShowPrompt(string message)
{
ToastContent toastContent = new ToastContent()
{
Launch = "bodyTapped",
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = message
},
}
}
},
Actions = new ToastActionsCustom()
{
Buttons = { new ToastButton("Yes", "Yes"), new ToastButton("No", "No") }
},
Header = new ToastHeader("header", "App", "header")
};
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
var promptNotification = new ToastNotification(doc);
promptNotification.Activated += PromptNotificationOnActivated;
DesktopNotificationManagerCompat.CreateToastNotifier().Show(promptNotification);
}
Event handler :
private void PromptNotificationOnActivated(ToastNotification sender, object args)
{
ToastActivatedEventArgs strArgs = args as ToastActivatedEventArgs;
switch (strArgs.Arguments)
{
case "Yes":
//stuff
break;
case "No":
//stuff
break;
case "bodyTapped":
//stuff
break;
}
}
This works in all cases, even when the toast is pushed back to the action center.
You can see it in action in an app that i made: NetStalker

What should the value of Windows.Current.Content be after opening a secondary window?

This is the suggested code in the App class from the Template10 article on implementing a shell:
public override Task OnInitializeAsync(IActivatedEventArgs args)
{
var nav = NavigationServiceFactory(BackButton.Attach, ExistingContent.Include);
Window.Current.Content = new Views.Shell(nav);
return Task.FromResult<object>(null);
}
The new shell object is assigned to Windows.Current.Content.
This is the suggested code for opening a secondary window (not with a shell), from the Template10 Secondary window example code:
var control = await NavigationService.OpenAsync(typeof(MySecondaryPage), null, Guid.NewGuid().ToString());
control.Released += Control_Released;
What is the relationship between Windows.Current.Content and the secondary window?
What is the relationship between Windows.Current.Content and the secondary window?
Actually, The NavigationService.OpenAsync method internally invoke ViewService.OpenAsync.
public async Task<IViewLifetimeControl> OpenAsync(UIElement content, string title = null,
ViewSizePreference size = ViewSizePreference.UseHalf)
{
this.Log($"Frame: {content}, Title: {title}, Size: {size}");
var currentView = ApplicationView.GetForCurrentView();
title = title ?? currentView.Title;
var newView = CoreApplication.CreateNewView();
var dispatcher = DispatcherEx.Create(newView.Dispatcher);
var newControl = await dispatcher.Dispatch(async () =>
{
var control = ViewLifetimeControl.GetForCurrentView();
var newWindow = Window.Current;
var newAppView = ApplicationView.GetForCurrentView();
newAppView.Title = title;
// TODO: (Jerry)
// control.NavigationService = nav;
newWindow.Content = content;
newWindow.Activate();
await ApplicationViewSwitcher
.TryShowAsStandaloneAsync(newAppView.Id, ViewSizePreference.Default, currentView.Id, size);
return control;
}).ConfigureAwait(false);
return newControl;
}
From the above code, you could get the app's Window(Singleton) has not been changed, when the second window activated, the Content of Window was replaced with second page. And when the previous window activated the Windows.Current.Content will turn the fist page back. And you could verify this with Window.Current.Activated event.
Window.Current.Activated += Current_Activated;
private void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
// check the sender
}

Tulpep PopupNotifier not working with Timer

using System;
using System.Data.SQLite;
using System.Drawing;
using System.Timers;
using System.Windows.Forms;
using Tulpep.NotificationWindow;
public partial class Form1 : Form
{
System.Timers.Timer timer = null;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
if (timer == null)
{
timer = new System.Timers.Timer();
timer.Elapsed += new System.Timers.ElapsedEventHandler(ObjTimer_Elapsed);
timer.Interval = 10000;
timer.Start();
}
}
private void ObjTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
PopupNotifier pop = new PopupNotifier();
pop.TitleText = "Test";
pop.ContentText = "Hello World";
pop.Popup();
//MessageBox.Show(""); !!! here is problem !!!
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Here i am using Tulpep notification for create desktop notification. I have one start button in my form. When start button clicked, timer start to pop desktop notification. But it is shows notification only when i not comment on MessageBox.Show("");. and if i remove or comment MessageBox.Show(""); it is not showing notification. I debug in both case, there is no error or exception in both case.
Is any one have idea why is this happening?
I am using .net framework 4.5.2,visual studio 2015, windows 8.
PopupNotifier needs to be called out of the UI-Thread. Since the handler of your timer runs in a different thread you need to invoke your form to solve the problem.
this.Invoke((MethodInvoker)delegate
{
PopupNotifier pop = new PopupNotifier();
pop.TitleText = "Test";
pop.ContentText = "Hello World";
pop.Popup();
});
Create a static class ControlExtensions:
public static void InvokeOnUiThreadIfRequired(this Control control, Action action)
{
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action.Invoke();
}
}
After that go again at the line where you call the Tulpep.NotificationWindow. and assign the main form to a variable like this:
//popup var is the notificationwindow inside form1
Form1 ff = (Form1)Application.OpenForms["Form1"];
ff.InvokeOnUiThreadIfRequired(() =>
{
ff.popup.Image = Properties.Resources.info_icon; //icon from resources
ff.popup.TitleText = title; // some text here
ff.popup.ContentText = contentMessage; // some text here
ff.popup.Popup();
});
Now you invoke the main form and show the NotificationWindow
I had the same problem but with Task.Run(), I tried calling Popup inside SomeMethod with no luck. Solved using Invoke. Hope this helps someone.
Task.Run(() => {
SomeMethod(); //Some method that executes in background
//Popup when SomeMethod is finished using Fruchtzwerg answer
this.Invoke((MethodInvoker)delegate
{
PopupNotifier pop = new PopupNotifier();
pop.TitleText = "Test";
pop.ContentText = "Hello World";
pop.Popup();
});
});

Open Windows Form with opcv From wpf windows

note I am new in Wpf >
I have project that decode qr code by using opencv library throw web cam >
and it running successfully
now I wanna to using this project in new Wpf project >
after adding new wpf project and make reference to WinForms application >
and this my simple code to open WinForm >
public void runnow(){
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CameraCapture.cameraCapture()); }
by ruining give me this exception >
The type initializer for 'Emgu.CV.CvInvoke' threw an exception.>
what can I do for solve this
C# code
public partial class CameraCapture : Form
{
Capture capture;
bool Capturing;
Bitmap bimap;
private Reader reader;
private Hashtable hint;
libAES libEncryption = new libAES();
string Mykey = "";
public static String dataDecrypted="";
public CameraCapture()
{
InitializeComponent();
}
private void Mains(object sender, EventArgs arg) // Start function main to encode Qr code
{
Image<Bgr, Byte> image = capture.QueryFrame();
if (image != null)
{
bimap = image.ToBitmap();
pictureBox1.Image = bimap;
reader = new QRCodeReader();
hint = new Hashtable(); // Add some elements to the hash table. There are no duplicate keys, but some of the values are duplicates.
hint.Add(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
RGBLuminanceSource source = new RGBLuminanceSource(bimap, bimap.Width, bimap.Height); //This class is used to help decode images from files which arrive as RGB data from* Android bitmaps. It does not support cropping or rotation.
BinaryBitmap img = new BinaryBitmap(new GlobalHistogramBinarizer(source));
Result result = null;
try
{
result = reader.decode(img, hint);
dataDecrypted = libEncryption.Decrypt(result.Text, Mykey);
}
catch
{
dataDecrypted = "";
}
if (result == null)
{
label1.Text = " no decode";
}
else
{
label4.Text = result.Text;
label1.Text = dataDecrypted;
capture.Dispose();
}
}
} // end function Main
private void btnStart_Click(object sender, EventArgs e)
{
if (capture == null)
{
try
{
capture = new Capture(); // **the exption thown here**
}
catch (NullReferenceException exception)
{
MessageBox.Show(exception.Message);
}
}
if (capture != null)
{
if (Capturing)
{
btnStart.Text = "Start Capture";
Application.Idle -= Mains;
}
else
{
btnStart.Text = "Stop Capture";
Application.Idle += Mains;
}
Capturing = !Capturing;
}
}
private void Release()
{
if (capture != null)
capture.Dispose();
}}
If you want to host WinForm in WPF, you need to use host control System.Windows.Forms.Integration.WindowsFormsHost
WPF provides many controls with a rich feature set. However, you may
sometimes want to use Windows Forms controls on your WPF pages. For
example, you may have a substantial investment in existing Windows
Forms controls, or you may have a Windows Forms control that provides
unique functionality.
Example code
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Create the interop host control.
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
// Create the MaskedTextBox control.
MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");
// Assign the MaskedTextBox control as the host control's child.
host.Child = mtbDate;
// Add the interop host control to the Grid
// control's collection of child controls.
this.grid1.Children.Add(host);
}
Check =>
http://msdn.microsoft.com/en-us/library/ms751761.aspx

Categories

Resources