Windows phone 8.1 universal app DataTransferManager UI not showing - c#

In my windows phone 8.1 universal app project I am trying to make a share option.
But when I click on the button (ShareCommand) the Share UI is not showing up, I have tried this in the emulator and on a device.
The event is correctly wired up since the DataRequested event gets called, but after this event there is no Share UI showing.
Here is the code I use in my ViewModel (using prism framework).
private DataTransferManager _dataTransferManager;
private DelegateCommand _shareCommand;
// Share button
public DelegateCommand ShareCommand
{
get
{
return _shareCommand ?? (_shareCommand = new DelegateCommand(() =>
{
DataTransferManager.ShowShareUI();
}));
}
}
public override async void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
// get data transfer manager and register events
_dataTransferManager = DataTransferManager.GetForCurrentView();
_dataTransferManager.DataRequested += DataTransferMangerDataRequested;
_dataTransferManager.TargetApplicationChosen += DataTransferMangerTargetApplicationChosen;
}
public override void OnNavigatedFrom(Dictionary<string, object> viewModelState, bool suspending)
{
base.OnNavigatedFrom(viewModelState, suspending);
// clean up events
_dataTransferManager.DataRequested -= DataTransferMangerDataRequested;
_dataTransferManager.TargetApplicationChosen -= DataTransferMangerTargetApplicationChosen;
}
private void DataTransferMangerTargetApplicationChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args)
{
}
private void DataTransferMangerDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var request = args.Request;
var deferral = request.GetDeferral();
request.Data.Properties.Title = "title test";
request.Data.Properties.Description = "description test";
request.Data.SetText("test hello");
request.Data.SetUri(new Uri("https://www.google.com"));
request.FailWithDisplayText("fail");
deferral.Complete();
}
I have tried setting different properties in the DataRequested event but still nothing.
Does anyone know what it could be? Do I need to set some permissions?
Edit:
Ok, weird I tried this in a new solution with only this code and it is working fine. But no idea why its not working in my current solution.

Ok I found out what was causing the problem.
I had to remove this, since this will cancel the operation. (I thought this will show if it failed for some reason and not cancel directly).
request.FailWithDisplayText("fail");

Related

C# WinUI TemplateStudio: how to prevent navigation during elaboration

In my app (C# + WinUI + Template Studio), I have an elaboration page and a left side Navigation Menu Items.
During the elaboration, I don't want that user can navigate to other pages.
What is the correct method to prevent this ?
I cannot find any example code to disable - temporarily - navigation.
I'm only capable to disable "back button" with:
Frame.BackStack.Clear();
I've tried to use App Service, like:
App.GetService<NavigationViewItem>().SelectsOnInvoked = false;
And also numerous variations, but without success, or looking for a "cancel event" when fired the:
private void OnNavigated(object sender, NavigationEventArgs e)
on "ShellViewModel", but cannot find it.
Thanks in advance for any suggestion.
You can just disable the NavigationView like this.
NavigationViewSerivice.cs
private async Task DoElaboration()
{
if (_navigationView is not null)
{
_navigationView.IsEnabled = false;
await Task.Delay(1000);
_navigationView.IsEnabled = true;
}
}
private async void OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
if (args.IsSettingsInvoked)
{
_navigationService.NavigateTo(typeof(SettingsViewModel).FullName!);
}
else
{
await DoElaboration();
var selectedItem = args.InvokedItemContainer as NavigationViewItem;
if (selectedItem?.GetValue(NavigationHelper.NavigateToProperty) is string pageKey)
{
_navigationService.NavigateTo(pageKey);
}
}
}

Silverlight Global Mouse Down Event Handler

I am desperately trying to implement a "Session Inactivity Timeout" for an IT security policy.
sss
However, my inactivity reset logic isn't firing. What am I doing wrong? I can't attach a breakpoint due to Visual Studio crashing on attaching to Silverlight binary. I am wondering if the problem is something very subtle, such as at the time the App constructor is called, there is no "current RootVisual" yet. Tagging with #WPF as well since #Silverlight is dead/obsolescent. Sample code below.
namespace TestApp
{
public partial class App : Application
{
System.Windows.Threading.DispatcherTimer sessionTimer = new System.Windows.Threading.DispatcherTimer();
public App()
{
ResetSessionTimer();
this.RootVisual.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(rootVisual_MouseLeftButtonDown), true);
//this.RootVisual.MouseLeftButtonDown += rootVisual_MouseLeftButtonDown;
InitializeComponent();
}
private void ResetSessionTimer()
{
sessionTimer.Stop();
sessionTimer.Tick -= sessionTimer_Tick;
sessionTimer = new System.Windows.Threading.DispatcherTimer();
sessionTimer.Interval = TimeSpan.FromMinutes(1);
sessionTimer.Tick += sessionTimer_Tick;
sessionTimer.Start();
}
private void sessionTimer_Tick(object sender, EventArgs e)
{
System.Windows.Browser.HtmlPage.Document.GetElementById("LogoutButton").Invoke("click", null);
}
private void rootVisual_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// added this alert to see if code is even firing.
System.Windows.Browser.HtmlPage.Window.Invoke("alert", "hello, world");
ResetSessionTimer();
e.Handled = false;
}
}
}
I figured this out - somewhere in the code, the previous developer was overriding the this.RootVisual element with a new MainPage() in order to enable their homegrown dependency injection / MVVM architecture. I moved the logic from the App() constructor to right after this assignment operator, and it works like magic.

Frame.Navigate in LoadState

I'm having trouble trying to navigate automatically between pages in my Windows 8.1 app based on a little check. It just doesn't want to navigate to another page when doing this in LoadState, as if something isn't loaded yet, but it doesn't give an error either. When I insert a delay using (for example) await Task.Delay(2000) before doing Frame.Navigate, then my app will redirect without any problem.
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
MyData oData = await getData();
if (oData != null)
{
this.Frame.Navigate(typeof(newPage), oData);
}
else
{
// do something else
}
}
Do I have to put this code in another load- or navigated-event? Or how can I make this work?
In LoadState and SaveState you should only save and restore the page state (called when suspending and reactivating the app). Do nothing else (like navigating).
Put your logic into the OnNavigatedTo method instead...
If you want to navigate from method that called when page is loads, you should place your navigation code to OnNavigatedTo(...). But do not forget to wrap your code in Dispatcher.RunAsync(...) - Frame navigation in xaml return false
I tried calling Frame.Navigate(...) from the OnNavigatedTo method but still the navigation didn't occur.
There are other answers which say use Dispatcher.RunAsync, but that feels like it's making assumptions about the threading model of Windows Phone.
Here's what I do: attach a handler to the Loaded event of the page instead, and put my "redirect" logic in there. Loaded fires after OnNavigateTo and after NavigationHelper_LoadState, but before the page has become visible.
public LaunchPadPage() {
this.InitializeComponent();
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
this.navigationHelper.SaveState += this.NavigationHelper_SaveState;
this.Loaded += LaunchPadPage_Loaded;
this.app = (App)App.Current;
}
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) {
// Let's show the root zone items
// NB: In case we don't have this data yet, do nothing
if (app.Hierarchy != null)
{
DefaultViewModel["Items"] = app.Hierarchy.RootItems;
}
}
private void LaunchPadPage_Loaded(object sender, RoutedEventArgs e) {
// No data? Go to the downloads page instead.
if (app.Hierarchy == null)
{
Frame.Navigate(typeof(DownloadingPage));
}
}

Windows Phone 8 canĀ“t call AudioVideoCaptureDevice second time

In my App you can open a Site where you can switch on and off the Flashlight.
The first time it works, but if I try to switch the flashlight on a second time the App crashes.
I think this is a Problem with AudioVideoCaptureDevice.OpenAsync. If I call it a second time the App crashes with a System.Reflection.TargetInvocationException WinRT-Informationen: Unable to acquire the camera. You can only use this class while in the foreground.
Someone know this Problem?
protected AudioVideoCaptureDevice Device { get; set; }
public Page10()
{
InitializeComponent();
}
async void tglSwitch_Checked(object sender, RoutedEventArgs e)
{
var sensorLocation = CameraSensorLocation.Back;
if (this.Device == null)
{
// get the AudioVideoCaptureDevice
this.Device = await AudioVideoCaptureDevice.OpenAsync(sensorLocation,
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(sensorLocation).First());
}
var supportedCameraModes = AudioVideoCaptureDevice
.GetSupportedPropertyValues(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchMode);
if (supportedCameraModes.ToList().Contains((UInt32)VideoTorchMode.On))
{
this.Device.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.On);
// set flash power to maxinum
this.Device.SetProperty(KnownCameraAudioVideoProperties.VideoTorchPower,
AudioVideoCaptureDevice.GetSupportedPropertyRange(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchPower).Max);
this.tglSwitch.Content = "Light on";
this.tglSwitch.SwitchForeground = new SolidColorBrush(Colors.Green);
}
}
void tglSwitch_Unchecked(object sender, RoutedEventArgs e)
{
var sensorLocation = CameraSensorLocation.Back;
sensorLocation = CameraSensorLocation.Back;
var supportedCameraModes = AudioVideoCaptureDevice
.GetSupportedPropertyValues(sensorLocation, KnownCameraAudioVideoProperties.VideoTorchMode);
if (this.Device != null && supportedCameraModes.ToList().Contains((UInt32)VideoTorchMode.Off))
{
this.Device.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.Off);
this.tglSwitch.Content = "Light off";
}
}
I would recommend to initialize the camera with OpenAsync ONE TIME in page lifecycle, for example in OnNavigatedTo event. And only makeSetProperty() methods calls code in your checkbox events to control light. It is also very important to dispose camera correctly then leaving the page, for example in OnNavigatedFrom event, by calling device.Dispose(). This option also make your flashlight to work faster.
Keep in mind that Windows Phone 8.1 now has dedicated API for torch, which works great and the code is more beautiful. You can use in Silverlight project as well, but you have to migrate your project. Here is more about this http://developer.nokia.com/community/wiki/Using_the_camera_light_in_Windows_Phone_7,_8_and_8.1 and https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.devices.torchcontrol.

How to subscribe to an event in a windows 8 settings panel (c#)

I'm developing a Windows 8 store application in c#/xaml. The windows store guidelines say that when a user changes a settings, the application should reflect that change immediately. I need help figuring out how to make this happen.
Here are some details about my setup.
I've created a custom control called OptionsView:
public partial class OptionsView : UserControl
{
public OptionsView()
{
this.InitializeComponent();
}
private void cmbEarliestYear_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
roamingSettings.Containers["appOptions"].Values["earliestYear"] = cmbEarliestYear.SelectedValue.ToString();
}
}
In my App.xaml.cs class, I'm using a SettingsFlyout from the Callisto library to display the custom options control when the user clicks on the Options link:
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
base.OnWindowCreated(args);
SettingsPane.GetForCurrentView().CommandsRequested += onCommandsRequested;
}
void onCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs eventArgs)
{
UICommandInvokedHandler optionsHandler = new UICommandInvokedHandler(onOptionsClick);
SettingsCommand optionsCommand = new SettingsCommand("options", "Options", optionsHandler);
eventArgs.Request.ApplicationCommands.Add(optionsCommand);
}
void onOptionsClick(IUICommand command)
{
SettingsFlyout settings = new SettingsFlyout();
settings.FlyoutWidth = SettingsFlyout.SettingsFlyoutWidth.Narrow;
settings.HeaderText = "Options";
settings.Content = new OptionsView();
settings.IsOpen = true;
}
I have a page in my application called CreateTripPage. There's a combobox on that page that allows the user to change the year of the trip. The earliest year in that combobox needs to change based on the value set by the user in Options. So, when the user changes the value of cmbEarliestYear in the OptionsView while the CreateTripPage is open, I need an event to fire. I can't figure out how to fire/subscribe to the needed event.
Any help would be appreciated.
Here is a simple example of similar behaviour I implemented. Cineworld app can be used to view details about cinemas / movies / in UK and Ireland.
Options page within Settings Pane, allows region to be selected / modified. This meant that my app needs to cater for region modification while it is running.
What I tend to do is this:
1) Have a config class that defines properties and persists those values.
2) The config class exposes a property
public static event Action RegionChanged = delegate { };
3) In setter of the Region property fire the event.
if (RegionChanged != null)
RegionChanged();
4) Now in MainPage.xaml.cs or the main app entry point.
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
Config.RegionChanged -= Config_RegionChanged;
Config.RegionChanged += Config_RegionChanged;
// do whatever else you need to do (initial data load)
base.OnNavigatedTo(e);
}
async void Config_RegionChanged()
{
bLoaded = false;
this.GoHome(this, new RoutedEventArgs());
}
That's it really.

Categories