UWP Custom Constructor when creating a secondary window - c#

I'm developing a quick application with the sole purpose of using picture-in-picture mode (compact view) in UWP to display Youtube videos over top of my work. Here's the way the current system works:
MainPage - Handles searching of youtube videos
YoutubeItem - A usercontrol that the mainpage creates for each youtube result. Approximately 50 of these are put into a wrap panel.
YoutubeViewer - A seperate page that runs in it's own window and displays the youtube video.
Here's my issue. I store all the information for the youtube video in each of the YoutubeItems. Using a button, I record the click event and handle it. Here's the code for handling the click:
private async void Button_Click(object sender, RoutedEventArgs e)
{
CoreApplicationView newView = CoreApplication.CreateNewView();
int newViewId = 0;
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame frame = new Frame();
frame.Navigate(typeof(YoutubeViewer), null);
Window.Current.Content = frame;
// You have to activate the window in order to show it later.
Window.Current.Activate();
newViewId = ApplicationView.GetForCurrentView().Id;
});
bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}
The problem arises when I have to send the link for the video to the YoutubeViewer. Originally, I was doing this through a constructor but upon using this method for the Windows Documentation, I am unable to use my own constructor from my knowledge. How would you folks recommend getting the link to the new window?

There are many ways.
the simplest, though not necessarily the most elegant, is to create a new class that inherits from Frameand add to it a property for the link. Something like this:
public class FooFrame: Frame
{
public string Link;
}
then in your code assign it upon initializing the frame:
FooFrame frame = new FooFrame(){Link = "youtube.link.com"}

Related

How to register a UWP app as share recipient for camera snapshot

In Windows 10, when I hit e.g. SHIFT + WIN + S I can take a screenshot of my screen.
In other cases I have my webcam that can take a picture, and so on.
All those scenarios have the feature to "Share" the captured image to another app, e.g. Mail, OneNote, etc.
I would like to register my own UWP app to be the recipient of such Share, so that the user can manipulate the captured image in my UWP app.
Is there a way to configure my UWP app to do this?
Is there a way to configure my UWP app to do this?
Yes, you could make your UWP app a receiver when you want to share some content from other apps.
Declare your app as a share target. Open the manifest file. Find the Declarations tab, then choose Share Target from the Available Declarations list, and then select Add.
Set the file types and formats based on your requirements in the Declarations. For example, if you need to receive a screenshot, you will need to add Bitmap in the Data format.
Handle share activation in the App.Xaml.cs by handling the Application.OnShareTargetActivated event.
I've made a simple test about this and you could refer to it. For more information about this, you could also check this document: Receive data
Manifest file:
App.xaml.cs:
protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
ShareOperation shareOperation = args.ShareOperation;
if (shareOperation.Data.Contains(StandardDataFormats.Bitmap))
{
var imageStream = await shareOperation.Data.GetBitmapAsync();
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(ShareImagePage), imageStream);
Window.Current.Activate();
}
}
ShareImagePage:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Content != null)
{
IRandomAccessStreamReference imageReceived = null;
imageReceived = e.Parameter as IRandomAccessStreamReference;
using (var imageStream = await imageReceived.OpenReadAsync())
{
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(imageStream);
imgImage.Source = bitmapImage;
}
}
}

IoTBrowser, navigate webview from task/thread

There's a webview:
<WebView x:Name="webView" Margin="0,10" Grid.RowSpan="3" LoadCompleted="webView_LoadCompleted"/>
And there's a basic snippet of code, which starts a task that will listen to an azure device. Some code is missing from the below example, presume the device was created normally.
The problem, is that I'd like to tell the Webview to navigate to a certain webpage, depending on the content of the received message.
The problem is,. "Window.Current" is null, so it crashes.
public App()
{
Task.Run(ReceiveC2dAsync);
}
private async static Task ReceiveC2dAsync()
{
while (true)
{
Microsoft.Azure.Devices.Client.Message receivedMessage = await deviceClient.ReceiveAsync();
if(receivedMessage != null)
{
// Snip
Task.Run(Navigate);
}
}
}
private async static Task Navigate()
{
try
{
if(Window.Current.Content != null)
((Frame)Window.Current.Content).Navigate(typeof(MainPage), "http://www.google.com");
}
catch(Exception e)
{
Debug.WriteLine("{0} Exception caught.", e);
}
}
In the override code:
protected override void OnLaunched(LaunchActivatedEventArgs e)
The following code can be used to navigate to a desired website when the application launches:
Frame rootFrame = Window.Current.Content as Frame;
if(rootFrame == null) rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage), "ms-appx-web:///help.html");
So, current is not null at this point.
If i save rootframe as a static, and use it at a later point in the task, I get a marshal error - basically stating the object is referenced to be marshaled to another thread.
My C# knowledge is,. in progress I fear.
So far I've been unable to find a proper explanation on how to have the webview respond to the internal task. Is it possible? And if so, how?
PS: The initial sample code is from: https://github.com/ms-iot/samples/tree/develop/IoTBrowser
The problem, is that I'd like to tell the Webview to navigate to a certain webpage
According to your code snippet, you are developing a UWP app. If you want to know how WebView navigate to a web site, you should be able to use Navigate method of WebView, for example:
webView.Navigate(new Uri("http://www.google.com"));
The following code can be used to navigate to a desired website when the application launches:
The code snippet by default inside OnLaunched navigate to one page by Frame. Frame control supports navigation to Page instances, not web pages, you cannot navigate to a website by Frame. Your above code snippet can only let the rootFrame navigate to MainPage, not the help.html. But you can get the ms-appx-web:///help.html parameter on MainPage and navigate to it by a WebView on MainPage.
I get a marshal error - basically stating the object is referenced to be marshaled to another thread.
If you want to invoke UIElement in a different thread, you should be able to use Core​Dispatcher, cannot invoke directly.
For a conclusion, I think what you actually want to do is navigate to a web site by WebView from a non UI thread. For example:
await Task.Run(Navigate);
private async Task Navigate()
{
try
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
webView.Navigate(new Uri("http://www.google.com"));
});
}
catch (Exception e)
{
Debug.WriteLine("{0} Exception caught.", e);
}
}

Windows Phone ContactPicker won't await properly

Although this has been posted before on StackOverflow but i think none of those reflect my issue and none of those solutions work for me either. So i'm developing a Windows Phone app and my workflow is a bit like this:
App starts
ContactPicker opens up
User selects one or multiple contacts
Based on how many contacts he selected, that many PivotItems are added into the Pivot.
My code is as follows:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
SelectContacts();
}
private async Task SelectContacts()
{
var picker = new ContactPicker();
picker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.PhoneNumber);
ContactsList = (List<Contact>)await picker.PickContactsAsync();
DisplayContacts();
}
private void DisplayContacts()
{
if (ContactsList != null)
{
foreach (var item in ContactsList)
{
PivotItem pivotItem = new PivotItem();
pivotItem.Header = item.FirstName.ToString();
ContentRoot.Items.Add(pivotItem);
}
}
}
According to me, in SelectContacts() method, the app should wait at the await call and once it gets back the list of contacts, than it should execute the DisplayContacts() method but its not working. I've tried multiple other variations of this code and they aren't working either.
await the SelectContacts() method and add the DisplayContacts() method beneath it. Remove the DisplayContacts() method from SelectContacts()
await SelectContacts();
DisplayContacts();
I don't know the complete reason why but i figured it out that since i was making the PickContactsAsync() call in the OnNavigatedTo() event, that is why it wasn't working as expected. Once i moved the PickContactsAsync() call into the PageLoaded() event handler, it started working as usual.

Don't have OnActivated method in app.xaml.cs Windows Phone 8.1

I'm actually working on an application which was a blank Windows Phone app 8.1 at the beginning. I wanted to implement the app with a FileOpenPicker to get a picture from the device. In WP 8.1, I have to use PickSingleFileAndContinue method of the OpenFilePicker. So I've read about configuring my project to handle Continue event here: your Windows Phone Store app after calling an AndContinue method MSDN. One of the steps is to implement the OnActivated method in the app.xaml.cs file.But there is no OnActivated method in my app.xaml.cs.
I've copy paste that method from the above link but the MainPage object used in that method doesn't have a Current state:
protected async override void OnActivated(IActivatedEventArgs e)
{
base.OnActivated(e);
continuationManager = new ContinuationManager();
Frame rootFrame = CreateRootFrame();
await RestoreStatusAsync(e.PreviousExecutionState);
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage));
}
var continuationEventArgs = e as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
Frame scenarioFrame = MainPage.Current.FindName("ScenarioFrame") as Frame;
if (scenarioFrame != null)
{
// Call ContinuationManager to handle continuation activation
continuationManager.Continue(continuationEventArgs, scenarioFrame);
}
}
Window.Current.Activate();
}
As I'm knew to Windows Phone and just facing the states management of an app, I cannot really figure out where that error comes from. Maybe someone got an idea ?
It won't be 100% clear until you download the full source code example off that link. They neglected to post the full example (too much code). Download the C# demo project and look at it.
MSDN FilePicker FULL SOURCE
public sealed partial class MainPage : Page
{
public static MainPage Current;
public MainPage()
{
this.InitializeComponent();
// This is a static public property that allows downstream pages to get a handle to the MainPage instance
// in order to call methods that are in this class.
Current = this;
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
}
As you can see it's just a static declaration.

How can I preload a page I want to navigate to?

I am building an app for WP8, and the MainPage.xaml takes a couple of seconds to load.
I want to add an animated Splash Screen, so here's what I did:
I created a new, and set it as the default navigation page
I put a StoryBoard animation in the page, with nothing else around, so that it loads fast
Now if I try to navigate to the main page from this page, it takes a couple of seconds becouse it has to load all the content as always.
A user here on stackoverflow wrote a sample of code to do something like this, saying that if you create a new instance of the page before navigating to it, it will cause the page to actually preload, making the navigation really fast.
Here's his code:
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
var sb = new Storyboard();
// create your animation here
sb.Completed += (sender, args) => PreLoad();
sb.Begin();
}
private void PreLoad()
{
// this is the part that actually takes time and causes things to get loaded
// you may need it in a try/catch block depending on what is in your constructor
var page = new PageToNavigateTo();
// now create an animation at the end of which we navigate away
var sbOut = new Storyboard();
// create your animation here
sbOut.Completed += (sender, args) => NavigateToNextScreen();
sbOut.Begin();
}
private void NavigateToNextScreen()
{
// navigate here
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
// remove the loading screen from the backstack so the user doesn't see it again when hitting the back button
NavigationService.RemoveBackEntry();
}
I just don't understand what he means with the line:
var page = new PageToNavigateTo();
What am I supposed to do there? I mean, which method do I have to call to create a new instance of the page I want to navigate to?
Also, inside the NavigateToNextScreen() method, do I have to use the usual
NavigationService.Navigate(new Uri("/CreditiInfo.xaml", UriKind.Relative));
or something else?
Could you help me completing this code? :)
Thank you!
Sergio
I would suggest that 'PageToNavigateTo()' should be the page constructor for the name of your next page. So in your case you would have:
var page = new MainPage();
For the navigation. That is the only way, that I know of navigating between pages on a Windows Phone 8 application.

Categories