Windows 10 Notification from desktop APP : OnActivated event - c#

I create a desktop app c# where i use some references :
using Microsoft.Toolkit.Uwp.Notifications;
using System.Windows;
using Windows.ApplicationModel.Activation;
using Microsoft.QueryStringDotNET;
And where i added some reference related to UWP application :
- Windows.System
- Windows.UI
- Windows.data
- Windows.Foundation
- Windows.ApplicationModel
Then i created a simple procedure to create and show my toast notification with the followin code :
private void Button_Click(object sender, RoutedEventArgs e)
{
var toastContent = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = "Surface Launch Party"
},
new AdaptiveText()
{
Text = "Studio S / Ballroom"
},
new AdaptiveText()
{
Text = "4:00 PM, 10/26/2015"
}
}
}
},
Actions = new ToastActionsCustom()
{
Inputs =
{
new ToastSelectionBox("status")
{
DefaultSelectionBoxItemId = "yes",
Items =
{
new ToastSelectionBoxItem("yes", "Going"),
new ToastSelectionBoxItem("maybe", "Maybe"),
new ToastSelectionBoxItem("no", "Decline")
}
}
},
Buttons =
{
new ToastButton("RSVP", "action=rsvpEvent&eventId=63851")
{
ActivationType = ToastActivationType.Foreground
},
new ToastButtonDismiss()
}
},
Launch = "action=viewEvent&eventId=63851"
};
Windows.Data.Xml.Dom.XmlDocument xmldoc = new Windows.Data.Xml.Dom.XmlDocument();
xmldoc.LoadXml(toastContent.GetContent());
var toast = new ToastNotification(xmldoc);
toast.Activated += OnActivated1;
// Create the toast notification
//var toastNotif = new ToastNotification(xmlDoc);
// And send the notification
ToastNotificationManager.CreateToastNotifier("Test").Show(toast);
Now my problem is that i don't know how to retrieve the item i selected in the list :-(
I created an procedure based toast.Activated event :
void OnActivated1(ToastNotification sender, object e)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
}
With this event, i can retrieve the argument (to know the button i clicked on) but getting the UserInput thanks to the class "ToastNotificationActivatedEventArgs" seems to be not possible...
Do you know if it's possible ? Is it a limitation of using reference UWP in a desktop app ?
Thank you very much !
Vincent

If you're building a Win32 Desktop app using the Desktop Bridge, you currently cannot use inputs and selection boxes in your toast, as there's no way to retrieve the input.
If you're building a normal Win32 app, you must set up a COM server to handle activation, which will include the inputs that the user selected. This quickstart explains how to set this up for normal Win32 apps. Plus, this will also allow your toasts to persist in Action Center, so if the user missed the popup, they can still access your toast from Action Center.

thank you for your answers.
The issue i have with my sub OnActivated :
void OnActivated1(ToastNotification sender, object e)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
}
is that the "e" object is recocgnized as a Windows.UI.Notifications.ToastActivatedEventsArgs and not as "ToastNotificationActivatedEventArgs" from Windows.ApplicationModel.Activation (where the properties Kind, UserInput.. should be very useful for me to get the content of selected item).
In my OnActivated1 sub, the var toastActivationArgs value equals to null because it cannot be converted to ToastNotificationActivatedEventArgs.
During my test the e.arguments equals to string "action=rsvpEvent&eventId=63851" but there is no XML returned. This is the only property available of the object e. (but this is useful to get the button where i clicked on)
I'm going to check the link from Andrew Bares to try to setup a COM server but i can see that's in c++ language..
Thank you !

The ToastNotificationActivatedEventArgs e.Arguments should be an xml string with what you need ready to parse.
First look at the string and see if it has what you need. Then go about using XMLReader or something to parse it.
Could you post the string you get?

Related

Windows Lock Screen, add Text programmatically

I want to display custom text or control on the Windows 10 Lockscreen, when I click on a button. I tried it with an UWP Application.
My goal is something like this:
And the Code I tried:
ToastContent content = new ToastContent()
{
//Duration = ToastDuration.Long,
Scenario = ToastScenario.Reminder,
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Attribution = new ToastGenericAttributionText()
{
Text = "Hello World"
}
}
},
Actions = new ToastActionsCustom()
{
Buttons = {
new ToastButton ("mycontent", "myargs")
}
}
};
var notification = new ToastNotification(content.GetXml());
ToastNotificationManager.CreateToastNotifier().Show(notification);
Also I saw this post and tried it of course, but it wasnt helpfull: Windows Lock Screen display text programmatically C#
Maybe you could help me to achive my goald
I thank you in advance
The screenshot you post above is smtc that used to show current playing music, for enable it you need to enable the app Background Media Playback, but it only use to show the media info, it can't use to share custom info like you mentioned scenario.
For your scenario, the better way is register your app LockScreen capability like the following.
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="xxxxx.UWP.App">
.......
<uap:LockScreen BadgeLogo="Assets\BadgeLogo.png" Notification="badgeAndTileText"/>
</uap:VisualElements>
</Application>
</Applications>
And set the app as main toast in the lock screen Setting page -> Personalization -> lock screen -> Choose one app to show detailed status on the lock screen If you have resisted the app, it will show in the apps list.
Code Sample
private void Button_Click(object sender, RoutedEventArgs e)
{
TileContent content = new TileContent()
{
Visual = new TileVisual()
{
LockDetailedStatus1 = "Hello world",
TileWide = new TileBinding() { }
}
};
var notification = new TileNotification(content.GetXml());
TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
}

C# Output To a Text Box

This is going to sound really stupid, but I'm taking a class in C# where we are skipping around the book and working only from a console application. We were given an exercise to build sentences in strings based on arrays of articles, nouns, verbs, and prepositions, and capitalize the first letter in the first word of the string. The kicker is, it wants the output to a text box. That wouldn't be a problem except
a) we have bypassed all chapters regarding GUIs (that will come in the next quarter's C# class), and
b) I have checked the book and even Stack Overflow and other online sources, but couldn't figure it out.
Unfortunately, my instructor chose not to discuss this exercise in class last night. Since he and I aren't on the same page (not a dislike, more of a chemistry thing), I'm trying to figure this out on my own. And the deadline for turning this in has passed, so I'm only asking for personal edification at this point.
So, here's the code I created. I wrote it for output to a console just to show I had the basic mechanism of the problem. I know I have to create a separate form with a text box inside a GUI window, but I couldn't figure out how to send the output to a text box rather than a console.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _16._4_StoryWriter
{
class StoryWriter
{
static void Main(string[] args)
{
string[] articles = { "the", "a", "one", "some", "any" };
string[] nouns = { "boy", "girl", "dog", "town", "car" };
string[] verbs = { "drove", "jumped", "ran", "walked", "skipped" };
string[] preps = { "to", "from", "over", "under", "on" };
string articleStory = "";
string nounStory = "";
string verbStory = "";
string prepStory = "";
Random random = new Random();
for (int counter = 1; counter <= 10; ++counter)
{
int randomNext = random.Next(5);
articleStory = articles[randomNext];
randomNext = random.Next(5);
nounStory = nouns[randomNext];
randomNext = random.Next(5);
verbStory = verbs[randomNext];
randomNext = random.Next(5);
prepStory = preps[randomNext];
Console.WriteLine(UppercaseFirst(articleStory) + " " + nounStory + " " + verbStory + " " + prepStory + ".");
} // End For
Console.Read();
} // End Main
static string UppercaseFirst(string s) // Borrowed from dotnetperls.com tutorial for making first letter uppercase
{
if (string.IsNullOrEmpty(s)) // Checks for an empty string
{
return string.Empty;
}
char[] a = s.ToCharArray(); // Creates array of characters from a string
a[0] = char.ToUpper(a[0]); // Selects value of zeroth position and changes to upper case
return new string(a); // Passes new string back
} // End method
} // End Class
} // End Namespace
To create a Windows Forms Application project Start Visual Studio
2010.
On the File menu, point to New, and then select Project.
The New Project dialog box appears.
In the Installed Templates pane, expand Visual Basic or Visual C#, and
then select Windows.
Above the middle pane, select the target framework from the drop-down
list.
In the middle pane, select the Windows Forms Application template.
NoteNote The Windows Forms Application template in the .NET Framework
4 targets the Client Profile by default.
In the Name text box, specify a name for the project.
In the Location text box, specify a folder to save the project. Click
OK.
The Windows Forms Designer opens and displays Form1 of the project.
SOURCE
Then drag textbox from toolbox and place it on the form.
Double click anywhere on the form, except for textbox, which will open code behind form and you will be in form load event.
Add:
textBox1.Text = "Your text to put in textbox";
in:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "Your text to put in textbox";
}
press F5
Youtube Form
Youtube textbox
You just need a Form and a TextBox as a child of the Form:
var form = new Form{Width = 300, Height = 100, Text = "The form"};
var textbox = new TextBox{Parent=form, Size = form.ClientRectangle.Size, Multiline = true};
textbox.Text = "Your Text";
form.ShowDialog();
You'll also need this using System.Windows.Forms somewhere and reference to System.Windows.Forms.dll

Declaring a new object via variable name

I'm fairly new to C# (and programming in general) so stick with me if I make any huge errors or talk complete bull.
So what I'm trying to do is have a private void that resizes the background image of a button. I send the name of the button to the private void via a string. Anyway, the code looks something like this:
ButtonResize("Zwaard");
protected void ButtonResize(string Button)
{
string ButNaam = "btn" + Button;
Button Butnaam = new Button();
Butnaam.Text = ButNaam;
if (Butnaam.BackgroundImage == null)
{
return;
}
else
{
var bm = new Bitmap(Butnaam.BackgroundImage, new Size(Butnaam.Width, Butnaam.Height));
Butnaam.BackgroundImage = bm;
}
}
But it doesn't work like that. I can't seem to find a way to declare a new object named the value I have in a string. What I want my code to do is instead of making a button called "Butnaam", I want it to create a button called btnZwaard (the value of the string Butnaam).
How do I tell C# I want the value of the variable to be the name of a new button, not literally what I type?
Thanks in advance.
Are you looking for something like this? By passing the Button to the method you can then act on the object. If this is what you are looking for then you should read Passing Reference-Type Parameters
protected void ButtonResize(Button button)
{
if (button != null && button.BackgroundImage != null)
{
button.BackgroundImage = new Bitmap(button.BackgroundImage, new Size(newWidth, newHeight));
}
}
A string is a piece of text. You subsequently refer to it as a class, which is wrong. Assuming it were right you create a new button rather than "resize its image".
What you want to do to get you started is create a new function in the same class as the dialog that has the button. That function can resize the image of the control.
Edit: this doesn't seem like a good starting point for learning a language, btw. Please find a good online tutorial for starting in C# (e.g. a hello world application).

Is it possible in MonoTouch to determine if the user clicked on an image in a BadgeElement?

I have amended the TODO list app to use a badge element instead of the boolean element as follows:
protected void PopulateTable()
{
tasks = TaskManager.GetTasks().ToList ();
UIImage ticked = new UIImage("checkbox_checked.png");
UIImage unticked = UIImage.FromFile("checkbox_unchecked.png");
Root = new RootElement("Tasky") {
new Section() {
from t in tasks
select (Element) new BadgeElement(t.Completed ? ticked : unticked, (t.Name==""?"<new task>":t.Name), delegate {
Console.WriteLine("???");
})
}
};
}
Is it possible to check to see if the user has clicked an icon rather than the text, and change the behaviour? Essentially I want to do this...
var task = tasks[indexPath.Row];
if(clickedIcon) {
currentTask = task;
task.Completed = !task.Completed;
TaskManager.SaveTask(currentTask);
} else {
ShowTaskDetails(task);
}
But I don't see any parameters inside IndexPath that allow me to access the column or the tapped element.
Any ideas
You need to create a custom version of the BadgeElement, and basically raise an event for the image that is separate from raising an event for the text.
Luckily for you, the whole source code is available, so you can just copy/paste BadgeElement, rename it, create a new unique key and modify it.

Receiving (dragged and) dropped Outlook contacts in C#?

I'm developing an application that needs to perform some processing on the user's Outlook contacts. I'm currently accessing the list of Outlook contacts by iterating over the result of MAPIFolder.Items.Restrict(somefilter), which can be found in Microsoft.Office.Interop.Outlook.
In my application, my user needs to choose several contacts to apply a certain operation on. I would like to add a feature that will allow the user to drag a contact from Outlook and drop it on a certain ListBox in the UI (I work in WPF but this is probably is more generic issue).
I'm very new to C# and WPF - how can I:
Receive a dropped item on a ListBox
Verify it's a ContactItem (or something that wraps ContactItem)
Cast the dropped item to a ContactItem so I can process it
Thanks
I tried this with a TextBox (no difference with a ListBox in practice).
Summary :
Searching in all outlook contacts for the one recieved dragged as text.
The search here is based on the person's FullName.
condition(s):
When you drag a contact, it must show the FullName when selected in outlook. The only catch is when two persons have the same full names!! If it's the case you can try to find a unique identifier for a person by combining ContactItem properties and searching them in the dragged text.
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetData("Text") != null)
{
ApplicationClass app;
MAPIFolder mapif;
string contactStr;
contactStr = e.Data.GetData("Text").ToString();
app = new ApplicationClass();
mapif = app.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderContacts);
foreach (ContactItem tci in mapif.Items)
{
if (contactStr.Contains(tci.FullName))
{
draggedContact = tci; //draggedContact is a global variable for example or a property...
break;
}
}
mapif = null;
app.Quit;
app = null;
GC.Collect();
}
}
of course this code is to be organized-optimized, it's only to explain the method used.
You can try using the Explorer.Selection property combined with GetData("Text") [to ensure it's coming from Outlook, or you can use GetData("Object Descriptor") in the DragOver Event, decode the memory stream, search for "outlook", if not found cancel the drag operation] And why not drag multiple contacts!
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetData("Text") != null)
{
ApplicationClass app;
Explorer exp;
List<ContactItem> draggedContacts;
string contactStr;
contactStr = e.Data.GetData("Text").ToString();
draggedContacts = new List<ContactItem>();
app = new ApplicationClass();
exp = app.ActiveExplorer();
if (exp.CurrentFolder.DefaultItemType == OlItemType.olContactItem)
{
if (exp.Selection != null)
{
foreach (ContactItem ci in exp.Selection)
{
if (contactStr.Contains(ci.FullName))
{
draggedContacts.Add(ci);
}
}
}
}
app = null;
GC.Collect();
}
}
An Outlook contact, when dropped, supports the following formats:
(0): "RenPrivateSourceFolder"
(1): "RenPrivateMessages"
(2): "FileGroupDescriptor"
(3): "FileGroupDescriptorW"
(4): "FileContents"
(5): "Object Descriptor"
(6): "System.String"
(7): "UnicodeText"
(8): "Text"
The most interesting looking one on that list (for me) is Object Descriptor, which then led me to someone with a similar sounding problem:
http://bytes.com/topic/visual-basic-net/answers/527320-drag-drop-outlook-vb-net-richtextbox
Where it looks like in that case, they detect that it's an Outlook drop, and then use the Outlook object model to detect what's currently selected, with the implication that that must be the current drop source.
What you could probably do is accept the drag and drop event in your .wpf app and then get the selected item(s) from outlook and pull them into your application.
Update
Add the Outlook PIA references to you app.
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.Explorer activeExplorer = app.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection currentSelection = activeExplorer.Selection;
Then you can iterate over the currentSelection collection to see what the user has dragged over.

Categories