Application name in Windows 10's timeline - WinForms - c#

I have the following code:
UserActivitySession _currentActivity;
private async Task GenerateActivityAsync()
{
// Get the default UserActivityChannel and query it for our UserActivity. If the activity doesn't exist, one is created.
UserActivityChannel channel = UserActivityChannel.GetDefault();
UserActivity userActivity = await channel.GetOrCreateUserActivityAsync("Test");
// Populate required properties
userActivity.VisualElements.DisplayText = ActivityName.Text; //ActivityName is textbox
userActivity.ActivationUri = new Uri(ActivityUri.Text); //ActivityUri is also textbox
userActivity.VisualElements.Description = "This is test item";
userActivity.VisualElements.Attribution =
new UserActivityAttribution(new Uri("http://via.placeholder.com/16x16"))
{ AlternateText = "Test123" };
//Save
await userActivity.SaveAsync(); //save the new metadata
// Dispose of any current UserActivitySession, and create a new one.
_currentActivity?.Dispose();
_currentActivity = userActivity.CreateSession();
}
And it results in something like on the screenshot: https://imgur.com/a/LK0NHAa
I want my app's name to be displayed after the dash character (the dash is inserted there by Windows).

You code specifies this:
userActivity.VisualElements.DisplayText = ActivityName.Text;
tried changing the DisplayText to the value you want?
Getting app name:
var pack = Package.Current.Id.Name;

Related

Bot mentions to meetings groups are blank on Desktop/Web chat view

We're developing a bot that proactively messages people in a group chat.
Bot mentions are showing blank on Desktop/Web chat view. Interestingly, on mobile and in the notification bar on the left, the full text does show correctly.
This issue may apply to other chats, but I have not tested.
I'm using similar code to the following Microsoft guide by constructing the mention object:
https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-and-group-conversations?tabs=dotnet#add-mentions-to-your-messages
Yes, I have tried using XMLConvert on the name as in the example, however, that does not make a difference, in fact, it puts the XML verbatim into the message sent by the bot.
I've also submitted a bug report here, as I suspect it's a bug in Teams itself (although, I could not find any other mentions of this or other similar example code):
https://microsoftteams.uservoice.com/forums/555103-public/suggestions/43922577-bot-mentions-to-meetings-groups-are-blank-on-deskt
Relevant C# code:
...
using (ConnectorClient _client = new ConnectorClient(new Uri(groupChat.ServiceUrl), GetMicrosoftAppCredentials(), new HttpClient()))
{
var theMessage = Activity.CreateMessageActivity();
theMessage.Text = messageDto.Message;
// Process the message text for <at>mentions</at>
var textMentions = System.Text.RegularExpressions.Regex.Matches(theMessage.Text, "<at>(.*?)</at>");
var mentionObjects = new List<Entity>(); // For storing the mentions
foreach (var textMention in textMentions)
{
// The mentioned person should be between the tags
var theName = textMention.ToString().Split(new string[] { "<at>", "</at>" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (!String.IsNullOrEmpty(theName))
{
// Find the teamsUser based on their name
var teamsUser = _botContext.Users.FirstOrDefault(u => u.Name.Equals(theName));
if (teamsUser != null)
{
var mention = new Mention
{
Mentioned = new ChannelAccount(teamsUser.TeamsUserId),
Text = textMention.ToString()
};
mentionObjects.Add(mention);
}
}
}
theMessage.Entities = mentionObjects;
try
{
var response = await _client.Conversations.SendToConversationAsync(groupChat.GroupChatId, (Activity)theMessage);
return Ok(response.Id);
}
catch (Exception e)
{}
}
...
Desktop Teams Chat:
Activity shows name OK:
Mobile app looks OK:
Images edited for privacy
Try passing "User Name" also in ChannelAccount() like below:
var mention = new Mention
{
Mentioned = new ChannelAccount(
turnContext.Activity.From.Id,
**turnContext.Activity.From.Name,**
role: null,
aadObjectId: null),
Text = textMention.ToString()
};
I tried above code and it's working for me.

How to load a specific dialog and it's resources without loading every dialog in the sample code?

Github link for the sample code I'm using
In the AdaptiveBot.cs file,
It creates a list of all the prompts available and takes user input and runs the specified prompt.
I want to modify it such that it loads only one dialog(There are 7 prompts in the sample folder and it gives a choice to load any one )
How would I go about to load only one dialog, for example just the MultiTurnPromptBot is needed to be loaded and the rest are not needed.
private void LoadDialogs()
{
System.Diagnostics.Trace.TraceInformation("Loading resources...");
//For this sample we enumerate all of the .main.dialog files and build a ChoiceInput as our rootidialog.
this.dialogManager = new DialogManager(CreateChoiceInputForAllMainDialogs());
this.dialogManager.UseResourceExplorer(this.resourceExplorer);
this.dialogManager.UseLanguageGeneration();
System.Diagnostics.Trace.TraceInformation("Done loading resources.");
}
private AdaptiveDialog CreateChoiceInputForAllMainDialogs()
{
var dialogChoices = new List<Choice>();
var dialogCases = new List<Case>();
foreach (var resource in this.resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".main.dialog")))
{
var name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(resource.Id));
dialogChoices.Add(new Choice(name));
var subDialog = resourceExplorer.LoadType<AdaptiveDialog>(resource);
dialogCases.Add(new Case($"{name}", new List<Dialog>() { subDialog }));
}
var dialog = new AdaptiveDialog()
{
AutoEndDialog = false,
Triggers = new List<OnCondition>() {
new OnBeginDialog() {
Actions = new List<Dialog>() {
new ChoiceInput() {
Prompt = new ActivityTemplate("What declarative sample do you want to run?"),
Property = "conversation.dialogChoice",
AlwaysPrompt = true,
Style = ListStyle.List,
Choices = new ChoiceSet(dialogChoices)
},
new SendActivity("# Running ${conversation.dialogChoice}.main.dialog"),
new SwitchCondition(){
Condition = "conversation.dialogChoice",
Cases = dialogCases
},
new RepeatDialog()
}
}
}
};
return dialog;
}
You can see that LoadDialogs is instantiating a dialog manager by passing an adaptive dialog into its constructor. So instead of creating the root dialog that starts all the other dialogs, you can just pass in one of those dialogs as the root dialog since they're all adaptive dialogs anyway. You can see that the declarative dialog files are loaded like this:
this.resourceExplorer.GetResources(".dialog")
And then the adaptive dialog instances are created out of them like this:
var subDialog = resourceExplorer.LoadType<AdaptiveDialog>(resource);
So you can do something like this:
private void LoadDialogs()
{
System.Diagnostics.Trace.TraceInformation("Loading resources...");
//For this sample we enumerate all of the .main.dialog files and build a ChoiceInput as our rootidialog.
//this.dialogManager = new DialogManager(CreateChoiceInputForAllMainDialogs());
this.dialogManager = new DialogManager(this.resourceExplorer.LoadType<AdaptiveDialog>(this.resourceExplorer.GetResource("MultiTurnPrompt.main.dialog")));
this.dialogManager.UseResourceExplorer(this.resourceExplorer);
this.dialogManager.UseLanguageGeneration();
System.Diagnostics.Trace.TraceInformation("Done loading resources.");
}
TL;DR: Replace this line:
this.dialogManager = new DialogManager(CreateChoiceInputForAllMainDialogs());
With this line:
this.dialogManager = new DialogManager(this.resourceExplorer.LoadType<AdaptiveDialog>(this.resourceExplorer.GetResource("MultiTurnPrompt.main.dialog")));

Is it possible to show animation in uwp toast notification?

I'm trying to understand if it's possible to show a countdown timer for example or some sort of animation or anything dynamic in toast notification?
Take a look at this article from Microsoft
https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-progress-bar
This shows how to add a progress bar to a Toast Notification in a UWP app.
First you create your Toast Notification with a specific tag
using Windows.UI.Notifications;
using Microsoft.Toolkit.Uwp.Notifications;
public void SendUpdatableToastWithProgress()
{
// Define a tag (and optionally a group) to uniquely identify the notification, in order update the notification data later;
string tag = "weekly-playlist";
string group = "downloads";
// Construct the toast content with data bound fields
var content = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = "Downloading your weekly playlist..."
},
new AdaptiveProgressBar()
{
Title = "Weekly playlist",
Value = new BindableProgressBarValue("progressValue"),
ValueStringOverride = new BindableString("progressValueString"),
Status = new BindableString("progressStatus")
}
}
}
}
};
// Generate the toast notification
var toast = new ToastNotification(content.GetXml());
// Assign the tag and group
toast.Tag = tag;
toast.Group = group;
// Assign initial NotificationData values
// Values must be of type string
toast.Data = new NotificationData();
toast.Data.Values["progressValue"] = "0.6";
toast.Data.Values["progressValueString"] = "15/26 songs";
toast.Data.Values["progressStatus"] = "Downloading...";
// Provide sequence number to prevent out-of-order updates, or assign 0 to indicate "always update"
toast.Data.SequenceNumber = 1;
// Show the toast notification to the user
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
Then you can use that tag to update the Toast Notification
using Windows.UI.Notifications;
public void UpdateProgress()
{
// Construct a NotificationData object;
string tag = "weekly-playlist";
string group = "downloads";
// Create NotificationData and make sure the sequence number is incremented
// since last update, or assign 0 for updating regardless of order
var data = new NotificationData
{
SequenceNumber = 2
};
// Assign new values
// Note that you only need to assign values that changed. In this example
// we don't assign progressStatus since we don't need to change it
data.Values["progressValue"] = "0.7";
data.Values["progressValueString"] = "18/26 songs";
// Update the existing notification's data by using tag/group
ToastNotificationManager.CreateToastNotifier().Update(data, tag, group);
}

How to set Publish Date in Word Document using OpenXML

I have a situation where a user can upload a word document which contains placeholders for certain properties (i.e. in MS Word the user has gone to Insert > Quick Parts > Document Properties and chosen a property). The specific properties I want to support are Title, Author, Company and Publish Date.
Title and Author are set as Package Properties, and Company is set as an Extended File Property. These are set with the below code, which works correctly:
private static void SetDocumentProperties(ReportTemplateModel model, WordprocessingDocument wordDocument)
{
//these properties always exist
wordDocument.PackageProperties.Title = model.Title;
wordDocument.PackageProperties.Creator = model.Author;
wordDocument.PackageProperties.Created = DateTime.Now;
wordDocument.PackageProperties.Modified = DateTime.Now;
//these properties can be null
if (wordDocument.ExtendedFilePropertiesPart == null)
{
wordDocument.AddNewPart<ExtendedFilePropertiesPart>();
}
if (wordDocument.ExtendedFilePropertiesPart.Properties == null)
{
wordDocument.ExtendedFilePropertiesPart.Properties = new Properties(new Company(model.SiteName));
}
else
{
wordDocument.ExtendedFilePropertiesPart.Properties.Company = new Company(model.SiteName);
}
}
My problem is that I can't work out how the set the Publish Date property. I have tried adding it as a Custom File Property using the below code (which is adapted from https://www.snip2code.com/Snippet/292005/WDSetCustomProperty), but this does not work. I've read a few things about setting custom properties, but I'm confused how they're meant to work. I'm also unsure if the Publish Date should actually be set as a custom property, or some other type of property.
var customProps = wordDocument.CustomFilePropertiesPart;
if (customProps == null)
{
customProps = wordDocument.AddCustomFilePropertiesPart();
customProps.Properties = new DocumentFormat.OpenXml.CustomProperties.Properties();
}
var properties1 = new DocumentFormat.OpenXml.CustomProperties.Properties();
//I have tried both of these lines, neither worked.
//properties1.AddNamespaceDeclaration("op", "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties");
properties1.AddNamespaceDeclaration("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
var customDocumentProperty1 = new DocumentFormat.OpenXml.CustomProperties.CustomDocumentProperty()
{
FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
PropertyId = 2,
Name = "Publish Date"
};
customDocumentProperty1.Append(new DocumentFormat.OpenXml.VariantTypes.VTLPWSTR { Text = DateTime.Today.ToShortDateString() });
properties1.Append(customDocumentProperty1);
part.Properties = properties1;
What type of property should the Publish Date be set as, and what is the right syntax for setting this?
Update: I have found that Publish Date is a CoverPageProperty which can be created using the below snippet, but I still haven't found how to set it correctly within the document.
var coverPageProps = new DocumentFormat.OpenXml.Office.CoverPageProps.CoverPageProperties
{
PublishDate = new PublishDate(DateTime.Today.ToShortDateString())
};
Adding the below code to my SetDocumentProperties method seems to work. I must admit I don't fully understand the below code, so any explanation would still be welcome. Additionally, if anyone has a solution which doesn't include writing XML as a string inside C# I would much prefer to avoid that.
const string publishDatePartId = "publishDatePart";
var publishDateXmlPart = wordDocument.MainDocumentPart.AddNewPart<CustomXmlPart>("application/xml", publishDatePartId);
var writer = new XmlTextWriter(publishDateXmlPart.GetStream(FileMode.Create), System.Text.Encoding.UTF8);
writer.WriteRaw($"<CoverPageProperties xmlns=\"http://schemas.microsoft.com/office/2006/coverPageProps\">" +
$"<PublishDate>{DateTime.Today.ToShortDateString()}</PublishDate>" +
$"</CoverPageProperties>");
writer.Flush();
writer.Close();
var customXmlPropertiesPart = publishDateXmlPart.AddNewPart<CustomXmlPropertiesPart>(publishDatePartId);
customXmlPropertiesPart.DataStoreItem = new DocumentFormat.OpenXml.CustomXmlDataProperties.DataStoreItem()
{
//I don't know what this ID is, but it seems to somehow relate to the Publish Date
ItemId = "{55AF091B-3C7A-41E3-B477-F2FDAA23CFDA}"
};

Cortana RequestDisambiguationAsync Error

I'm trying to get user interaction with a background app through Cortana working for my app.
Whenever I do RequestDisambiguationAsync(response) Cortana just says that it ran into an error. However, it isn't breaking anywhere in Visual Studio.
Any ideas on what may be causing it? Below is the code that I am using:
var userPrompt = new VoiceCommandUserMessage();
string home1 = data.Structures[0].Name;
string home2 = data.Structures[1].Name;
userPrompt.DisplayMessage = "Which one did you want to set to home?";
userPrompt.SpokenMessage = String.Format("Which one did you want to set to home? {0} or {1}?", home1, home2);
var userReprompt = new VoiceCommandUserMessage();
userReprompt.DisplayMessage = "Which one did you want to set to home?";
userReprompt.SpokenMessage = "Which one did you want to set to home?";
var structuresContentTiles = new List<VoiceCommandContentTile>();
var structureTile = new VoiceCommandContentTile();
structureTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
structureTile.Title = home1;
structureTile.AppContext = data.Structures[0].Structure_id;
structuresContentTiles.Add(structureTile);
var structureTile2 = new VoiceCommandContentTile();
structureTile2.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
structureTile2.Title = home2;
structureTile.AppContext = data.Structures[1].Structure_id;
structuresContentTiles.Add(structureTile2);
var response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt, structuresContentTiles);
var voiceCommandDisambiguationResult = await voiceServiceConnection.RequestDisambiguationAsync(response);
This behavior can occur in some cases when you use
structureTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
but do not supply an image. Change it to VoiceCommandContentTileType.TitleOnly, or if you're supplying a Line1, use VoiceCommandContentTileType.TitleWithText, or provide an Image, and that should stop the failure from occurring.

Categories

Resources