I am looking for a possibility to start my own Windows App after some content is shared with it through the charm bar. I have found this MS example https://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782/ But after the share button is clicked the app closes. I have tryed it this code at the button click method:
var rootFrame = new Frame();
rootFrame.Navigate(typeof(DefaultPage));
Window.Current.Content = rootFrame;
Window.Current.Activate();
But this has no effect. Also I have tryed to use Application.Start() but the parameter should be a Callback and I don't understand which one.
-------Edit: I want the following behavior.
So I can't find a solution for the last step. Switching from the Sharing page of my app to the Main Page of my app.
Edit End-------
Every thing I want is to start my App after some content is shared with it. I hope somebody can help me. Or is this not possible?
----Edit 2:
App.xaml.cs:
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
namespace AppName
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
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();
// Set the default language
rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
/// <summary>
/// Invoked when the application is activated as the target of a sharing operation.
/// </summary>
/// <param name="e">Details about the activation request.</param>
protected override void OnShareTargetActivated(Windows.ApplicationModel.Activation.ShareTargetActivatedEventArgs e)
{
var shareTargetPage = new AppName.ShareTargetPage();
shareTargetPage.Activate(e);
Window.Current.Activate();
}
protected override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
}
}
}
Mainpage.xaml.cs:
using System;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace AppName
{
/// <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();
}
public void ReceiveUri(Uri sharedWebLink)
{
tbMessages.Text = sharedWebLink.ToString();
}
protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
// It is possible to get in this method after the Share button at the
// sharetargetpage is clicked but at this point I don't know how to
// activate the app
//base.OnNavigatedTo(e);
}
}
}
Sharepargetpage.xaml.cs:
using Windows.UI.Core;
using AppName.Common;
using System;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
// The Share Target Contract item template is documented at http://go.microsoft.com/fwlink/?LinkId=234241
namespace AppName
{
/// <summary>
/// This page allows other applications to share content through this application.
/// </summary>
public sealed partial class ShareTargetPage : Page
{
private Uri sharedWebLink;
/// <summary>
/// Provides a channel to communicate with Windows about the sharing operation.
/// </summary>
private Windows.ApplicationModel.DataTransfer.ShareTarget.ShareOperation _shareOperation;
private ObservableDictionary defaultViewModel = new ObservableDictionary();
/// <summary>
/// This can be changed to a strongly typed view model.
/// </summary>
public ObservableDictionary DefaultViewModel
{
get { return this.defaultViewModel; }
}
public ShareTargetPage()
{
this.InitializeComponent();
}
/// <summary>
/// Invoked when another application wants to share content through this application.
/// </summary>
/// <param name="e">Activation data used to coordinate the process with Windows.</param>
public async void Activate(ShareTargetActivatedEventArgs e)
{
this._shareOperation = e.ShareOperation;
// Communicate metadata about the shared content through the view model
var shareProperties = this._shareOperation.Data.Properties;
var thumbnailImage = new BitmapImage();
this.DefaultViewModel["Title"] = shareProperties.Title;
this.DefaultViewModel["Description"] = shareProperties.Description;
this.DefaultViewModel["Image"] = thumbnailImage;
this.DefaultViewModel["Sharing"] = false;
this.DefaultViewModel["ShowImage"] = false;
this.DefaultViewModel["Comment"] = String.Empty;
this.DefaultViewModel["Placeholder"] = "Add a comment";
this.DefaultViewModel["SupportsComment"] = true;
Window.Current.Content = this;
Window.Current.Activate();
try
{
this.sharedWebLink = await this._shareOperation.Data.GetWebLinkAsync();
this.DefaultViewModel["URL"] = this.sharedWebLink.ToString();
}
catch (Exception ex)
{
NotifyUserBackgroundThread("Failed GetWebLinkAsync - " + ex.Message, NotifyType.ErrorMessage);
}
// Update the shared content's thumbnail image in the background
if (shareProperties.Thumbnail != null)
{
var stream = await shareProperties.Thumbnail.OpenReadAsync();
thumbnailImage.SetSource(stream);
this.DefaultViewModel["ShowImage"] = true;
}
}
/// <summary>
/// Invoked when the user clicks the Share button.
/// </summary>
/// <param name="sender">Instance of Button used to initiate sharing.</param>
/// <param name="e">Event data describing how the button was clicked.</param>
private void ShareButton_Click(object sender, RoutedEventArgs e)
{
this.DefaultViewModel["Sharing"] = true;
this._shareOperation.ReportStarted();
// TODO: Perform work appropriate to your sharing scenario using
// this._shareOperation.Data, typically with additional information captured
// through custom user interface elements added to this page such as
// this.DefaultViewModel["Comment"]
this._shareOperation.ReportCompleted();
// TRY1: Navigate to MainPage
//Frame rootFrame = Window.Current.Content as Frame;
//if(rootFrame == null)
//{
// rootFrame = new Frame();
// Window.Current.Content = rootFrame;
//}
//if(rootFrame.Content == null)
//{
// rootFrame.Navigate(typeof(MainPage));
//}
// TRY2: Navigate to MainPage
//var p = rootFrame.Content as MainPage;
//p.ReceiveUri(sharedWebLink);
//Window.Current.Activate();
var rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage));
Window.Current.Content = rootFrame;
Window.Current.Activate();
// TRY3: Start the App
// Application.Start();
// App.Start();
// but I don't know which callback method should be the param of start
}
async private void NotifyUserBackgroundThread(string message, NotifyType type)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
NotifyUser(message, type);
});
}
private void NotifyUser(string strMessage, NotifyType type)
{
switch (type)
{
// Use the status message style.
case NotifyType.StatusMessage:
StatusBlock.Style = Resources["StatusStyle"] as Style;
break;
// Use the error message style.
case NotifyType.ErrorMessage:
StatusBlock.Style = Resources["ErrorStyle"] as Style;
break;
}
StatusBlock.Text = strMessage;
}
public enum NotifyType
{
StatusMessage,
ErrorMessage
};
}
}
Edit 2 End ---------
To enable your app's behavior as Share Targeted app, you have to override OnShareTargetActivated(ShareTargetActivatedEventArgs args)
method in App
class.
protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
var rootFrame = new Frame();
// TODO: Load content in frame
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
EDIT
From your current implementation you are going to setShareTargetPage
inside windows and later you cast Windows.Current.Content
to Frame
that is always null. So, you can't do this way. My recommendation is to do it this way.
Change OnShareTargetActivated
method inside App.xaml.cs to this
protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
var rootFrame = new Frame();
rootFrame.Navigate(typeof(ShareTargetPage), args);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
Remove this from Activate
method in ShareTargetPage.xaml.cs
Window.Current.Content = this;
Window.Current.Activate();
Overrides OnNavigatedTo
in ShareTargetPage
class
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Calling Activate method here
Activate((ShareTargetActivatedEventArgs)e.Parameter);
}
And then to navigate to another page you can simply Calls Frame.Navigation
something like that inside ShareTargetPage
this.Frame.Navigate(typeof(MainPage));
EDIT 2
If you want to navigate to another page on share button click then remove this line of code
this._shareOperation.ReportCompleted();
This calling above method informs the OS that your app has finished sharing request and is now safely terminated. That's why your app terminates without navigation to another page