C# ToastButton callback function - c#

I've created a toast-message in WPF, with a button.
public void ShowToast(string message)
{
var toastButton = new ToastButton();
toastButton.ActivationType = ToastActivationType.Foreground;
toastButton.SetContent("Reconnect");
toastButton.AddArgument("action", "like");
var toast = new ToastContentBuilder()
.AddText("VPN Notifications")
.AddText(message)
.AddButton(toastButton).SetBackgroundActivation();
toast.Show();
}
How can I get the button callback in my C# dotnet 6 app?

Related

Facing Issues in WinForm Integration with my Existing Azure Bot Using Directline API

I have created a bot using Bot Framework SDK (C#, .Net). I have published it in Azure. It is working fine in WebChat as well as in Teams channel. Now I want to create one Winform and trying to connect the Winform UI to my bot using Directline Api.
This is my code :
public partial class Form1 : Form
{
private static string directLineSecret = ConfigurationSettings.AppSettings["DirectLineSecret"];
private static string botId = ConfigurationSettings.AppSettings["BotId"];
private static string fromUser = "User";
private static string id = "default-user";
private Conversation conversation;
DirectLineClient directLineClient = null;
public Form1()
{
InitializeComponent();
InitClientAsync();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private async Task InitClientAsync()
{
directLineClient = new DirectLineClient($"{directLineSecret}");
directLineClient.BaseUri = new Uri($"https://directline.botframework.com/");
//directLineClient = new DirectLineClient(directLineSecret);
conversation = await directLineClient.Conversations.StartConversationAsync().ConfigureAwait(false);
new System.Threading.Thread(async () => await ReadBotMessageAsync(directLineClient, conversation.ConversationId)).Start();
}
private async Task ReadBotMessageAsync(DirectLineClient client, string conversationId)
{
string watermark = null;
while(true)
{
var activitySet = await client.Conversations.GetActivitiesAsync(conversationId, watermark);
watermark = activitySet?.Watermark;
var activities = from x in activitySet.Activities where x.From.Id == botId select x;
foreach(Activity activity in activities)
{
if(activity.Text != null)
{
string message = activity.Text;
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate
{
textBox.AppendText("Bot : " + message + "\r\n");
}));
}
}
}
}
}
private async void btn_Send_Click(object sender, EventArgs e)
{
string input = txt_Send.Text;
txt_Send.Clear();
if(input.Length>0)
{
Activity userMessage = new Activity
{
From = new ChannelAccount(id, fromUser),
Text = input,
Type = ActivityTypes.Message,
TextFormat = "plain"
};
textBox.AppendText("You : " + input + "\r\n");
await directLineClient.Conversations.PostActivityAsync(this.conversation.ConversationId, userMessage);
}
}
}
But when I execute the program it is stopping due to Null reference exception when it is trying to get conversation as well as conversation Id.
you can check the error image here.
Can anyone please tell me what I'm missing here?
Any help will be appreciated.....
The problem was with the directline secret key. I regenerate a new key and used it. Now that is starting the conversation and I am able to see conversation Id.
But after that I was getting status code 429 error. That is basically Multiple thread issue. It is trying to create multiple threads at the same time.
Then I recreate the whole project with .Net Framework version 4.6.2 (Previously using 4.7). Now that issue also got resolved. Project is working fine.

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

NFC-reader on Win IOT: Pin ' is currently opened in an incompatible sharing mode

I am working on a NFC reader project based on Windows 10 IoT running on a Rasperry PI 3.
I use the library Mfrc522lib.cs found here: RFID RC522 Raspberry PI 2 Windows IOT.
I use an async task to wait for the card. It scans perfect the first time, but when I start the task again (for test puprose with button).
I get this:
Pin ' is currently opened in an incompatible sharing mode. Make sure this pin is not already in use by this application or another Application
Any idea?
public MainPage()
{
this.InitializeComponent();
startNFC();
}
public void startNFC()
{
var read = ReadNFCAsync();
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
this.serial.Text = "Klar for å lese kortet ditt";
this.statusline.Fill = new SolidColorBrush(Colors.Green);
});
read.ContinueWith(prev => {
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
this.serial.Text = prev.Result.ToString();
this.statusline.Fill = new SolidColorBrush(Colors.Orange);
});
});
}
public static async Task<String> ReadNFCAsync()
{
await Task.Delay(1000);
var mfrc = new Mfrc522();
await mfrc.InitIO();
while (true)
{
if (mfrc.IsTagPresent())
{
var uid = mfrc.ReadUid();
var serial= uid.ToString();
mfrc.HaltTag();
return serial;
}
}
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
startNFC();
}
This issue due to initializing GPIO pin is in use. Because every time you click the button the following line will be executed:
await mfrc.InitIO();
To solve this problem you can edit your code like this:
private Mfrc522 mfrc = new Mfrc522();
public static bool IsGpioInitialized = false;
public async Task ReadNFCAsync()
{
if (!IsGpioInitialized)
{
await mfrc.InitIO();
IsGpioInitialized = true;
}
}

UWP Toast Notification debugging in Visual Studio - no toast displaying, "Returned with error code 0x0"

I have a background task that is supposed to open a toast message, à la: ToastNotificationManager.CreateToastNotifier().Show(toast);. My code executes fine, no errors are thrown, nothing hangs -- but also, no toast message appears.
I checked the Event Viewer logs, and they say this:
An instance of the background task with entry point
BG.ToastBackgroundTask running for user [me] in session [sesh]
returned with error code 0x0.
I have looked all over to see what this error code might mean but found nothing.
Here's my code:
public sealed class ToastBackgroundTask : IBackgroundTask
{
private BackgroundTaskDeferral _deferral;
public async void Run(IBackgroundTaskInstance taskInstance)
{
var cancelToken = new System.Threading.CancellationTokenSource();
taskInstance.Canceled += (s, e) =>
{
cancelToken.Cancel();
cancelToken.Dispose();
};
taskInstance.Task.Completed += Task_Completed;
_deferral = taskInstance.GetDeferral();
try
{
await SendNotificationAsync();
}
finally { _deferral.Complete(); }
}
public static async void Register()
{
var isRegistered = BackgroundTaskRegistration.AllTasks.Values.Any(x => x.Name == nameof(ToastBackgroundTask));
if (isRegistered) return;
var accessStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (accessStatus == BackgroundAccessStatus.DeniedByUser || accessStatus == BackgroundAccessStatus.DeniedBySystemPolicy) return;
var builder = new BackgroundTaskBuilder
{
Name = nameof(ToastBackgroundTask),
TaskEntryPoint = $"{nameof(MyNameSpace)}.{nameof(BG)}.{nameof(ToastBackgroundTask)}"
};
builder.SetTrigger(new TimeTrigger(120, false));
var task = builder.Register();
}
private static void Task_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
try
{
args.CheckResult();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private Task SendNotificationAsync()
{
var service = new ToastService();
service.CreateToast(new ToastViewModel { Title = "Title", Text = "Text", ImagePath = "", Id = 3 });
return Task.CompletedTask;
}
}
If I run CheckResult() on the completed task, no errors are thrown. Argh! Does anyone know (a) what this Event Viewer log error means, or (b) why my toast isn't showing up?
Here's my Toast code too in case it helps:
public class ToastService
{
public void CreateToast(ToastViewModel model)
{
var visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText() { Text = model.Title },
new AdaptiveText() { Text = model.Text }
},
Attribution = new ToastGenericAttributionText() { Text = "Via Me" }
}
};
var tContent = new ToastContent()
{
Visual = visual,
ActivationType = ToastActivationType.Background,
Scenario = ToastScenario.Reminder
};
var toast = new ToastNotification(tContent.GetXml())
{
ExpirationTime = DateTime.Now.AddDays(model.Expiration)
};
toast.Failed += (o, args) => {
var message = args.ErrorCode;
};
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
Does anyone know (a) what this Event Viewer log error means, or (b) why my toast isn't showing up?
The above event log showed on my side is information level, not error level. The reason for the toast isn't showing up should be that you setting the ExpirationTime property for the ToastNotification. This property is for:
Gets or sets the time after which a toast notification should not be displayed.
So that if the model.Expiration equals to 0, the toast will not show from now. Ensure the expiration time later than now should work.
var toast = new ToastNotification(tContentxml)
{
ExpirationTime = DateTime.Now.AddDays(1)
};
Otherwise your code snippet can work will on my side. If you still have issues, you can provide a minimal reproduced project to let us have a testing.

Windows Universal ToastNotification not displayed, But available in Action Center

I create and post a Toast as follows:
public async Task Handle(Alert a) {
var tst = String.Format(#"<toast><visual><binding template='ToastGeneric'><text>Alert</text><text>{0}</text></binding></visual></toast>", a.Msg);
var xml = new XmlDocument();
xml.LoadXml(tst);
var tn = new ToastNotification(xml);
var t = new TaskCompletionSource<bool>();
tn.Dismissed += (s, e) => {
t.TrySetResult(true);
PersistLog.i(TAG, "Handle:Toast Dismissed:" + e.Reason);
};
tn.Failed += (s, e) => {
t.TrySetResult(false);
PersistLog.i(TAG, "Handle:Toast Failed");
};
*/
ToastNotificationManager.CreateToastNotifier().Show(tn);
var how = await t.Task;
}
The Toast Never displays. If Does call the Dismissed CB ... and the Reason is UserCancelled. Why ??? It does show up in the Windows 10 (Anniversary) Action Center.
I have tried calling this from a UI thread as well from the App's OnBackgroundActivated event. The latter is where I really want to call this from ... I want to display a Toast when my App is activated as a Background task from an WNS event.

Categories

Resources