How to update tile created by other app? - windows-phone

I have two app: one UI to create a tile with Create(), the other agent to update the tile with Update(). The 2 functions worked well in one app, ie. both in UI or both in agent. But if I put Create in UI and Update() in agent, Update() can not find the tile created by Create(). What's wrong? Thanks.
private void Create()
{
ShellTile find = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("ID=shelltile"));
StandardTileData date = new StandardTileData();
date.Count = 10;
if (find == null)
{
ShellTile.Create(new Uri("/MainPage.xaml?ID=shelltile", UriKind.Relative), date);
}
}
private void Update()
{
ShellTile find = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("ID=shelltile"));
if (find != null)
{
StandardTileData date = new StandardTileData();
date.Title = "aaaaaaaaa";
find.Update(date);
}
}

Each app can only access its own tiles. If you want to update the tiles, you'll need to make a background agent in the same app. (note that a background agent can't create tiles, which leads me to believe this isn't what you're doing now)

Related

How can I get a list of variables and assignments / default values?

We have a collection of Microsoft Windows Workflows (.xaml files) that I need to go through and inventory the variables. The workflows are complicated with variables scoped at many levels so I can't simply open up the Workflow xaml and look at the Variables tab at the top level; I need to dig through each level, sequence, etc. to find all possible variable definitions.
Can I automate this process? Can Visual Studio aid in this process?
One solution, I could write some code to read the workflow file, look for variables, grab any default values, and check if the variable is assigned, thus overriding the default. Technically, this is possible from C#. But is this solution really necessary to get the information?
You can use a recursive function like this:
List<Variable> Variables;
private void GetVariables(DynamicActivity act)
{
Variables = new List<Variable>();
InspectActivity(act);
}
private void InspectActivity(Activity root)
{
IEnumerator<Activity> activities = WorkflowInspectionServices.GetActivities(root).GetEnumerator();
while (activities.MoveNext())
{
PropertyInfo propVars = activities.Current.GetType().GetProperties().FirstOrDefault(p => p.Name == "Variables" && p.PropertyType == typeof(Collection<Variable>));
if (propVars != null)
{
try
{
Collection<Variable> variables = (Collection<Variable>)propVars.GetValue(activities.Current, null);
variables.ToList().ForEach(v =>
{
Variables.Add(v);
});
}
catch
{
}
}
InspectActivity(activities.Current);
}
}
And should be called like this:
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xamlData)))
{
XamlXmlReaderSettings readerSettings = new XamlXmlReaderSettings()
{
LocalAssembly = Assembly.GetExecutingAssembly()
};
var xamlReader = new XamlXmlReader(stream, readerSettings);
Activity activity = ActivityXamlServices.Load(xamlReader);
DynamicActivity root = activity as DynamicActivity;
GetVariables(root);
}
Credit to: https://stackoverflow.com/a/11429284/593609

Getting code to run on all pages based on date

I am trying to create a program that has two main parts: Projects and Audits
A Project will have a start date and a number that will tell it how many days until completion (they're all preset).
I need an Audit to be created say one day before the Project is complete.
No big deal so far.
The problem I forsee and am struggling with how to answer is:
How can I efficiently maintain this? I am using MVC4 and have tried Action Filters. I have the code running on every page - to cover any custom urls accessing the site. However, this seems to slow things down considerably. Here's what I have so far:
public class CreateAuditsController : ActionFilterAttribute
{
private QAAPPEntities db = new QAAPPEntities();
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
CreateAuditsFromProjects();
base.OnActionExecuted(filterContext);
}
public void CreateAuditsFromProjects()
{
// Generate list of Research Projects
List<ResearchProject> allResearchProjects = db.ResearchProjects.Include(a => a.ResearchProjectStatus).ToList();
// Cycle through those to see which ones need audits created
for (int i = 0; i < allResearchProjects.Count; i++)
{
// Get current looped project for further use
ResearchProject currentLoopedProject = allResearchProjects[i];
if (currentLoopedProject.Description == "Some Description")
{
Audit auditToAdd = new Audit();
auditToAdd.ResearchProjectID = currentLoopedProject.ResearchProjectID;
auditToAdd.Name = "Some Name";
auditToAdd.AssignedQAID = 1;
auditToAdd.CreatedDate = DateTime.Now;
auditToAdd.AuditStatusID = 1;
auditToAdd.AuditTypeID = 1;
db.Audits.Add(auditToAdd);
db.SaveChanges();
}
}
db.SaveChanges();
// Create audits
}
}
Any help is appreciated.
Check out Revalee. It let's you schedule actions to be taken at a later time. So, when you create a project, you would then use the Revalee client to schedule an audit to be created one day before it ends.
Simple solution is that, create a database event with the logic of checking all projects with one day left and add a record in audit table for each of those projects.
Thank you.

Loading Contacts on Key Down in ListView

I am using following code to load contacts using ContactStore. My requirement is to search contacts in ContactStore when key is pressed in a textbox. Below is the code in my View Model.
private async void LoadAllContacts(string searchQuery)
{
ContactStore contactStore = await ContactManager.RequestStoreAsync();
IReadOnlyList<Contact> contacts = null;
// Find all contacts
contacts = await contactStore.FindContactsAsync(searchQuery);
foreach (var item in contacts)
{
if (!string.IsNullOrEmpty(item.FirstName) && !string.IsNullOrEmpty(item.LastName))
{
var contact = new Member
{
FirstName = item.FirstName,
LastName = item.LastName,
FullName = item.DisplayName, //item.HonorificNamePrefix ?? "" + item.FirstName + item.MiddleName ?? "" + item.LastName,
Bio = item.Notes
};
if (item.DataSuppliers != null)
{
foreach (var dataSupplier in item.DataSuppliers)
{
switch (dataSupplier.ToLower())
{
case "facebook":
break;
case "hotmail2":
case "hotmail":
break;
}
}
}
if (item.Thumbnail != null)
{
var thumnailStream = await item.Thumbnail.OpenReadAsync();
BitmapImage thumbImage = new BitmapImage();
thumbImage.SetSource(thumnailStream);
contact.ImageSource = thumbImage;
}
this.Insert(0, contact);
}
}
}
The contacts are loading perfectly in my listview but the problem is that loading contacts from contact store is an extensive task and when user I press text in the textbox quickly then application throws exception.
My question is how can I load contacts efficiently? Means if User pressed 'a' and I call this method and quickly user pressed 'c' so if the results are loaded for 'a' then application should cancel continuing with previous operation and load 'ac' related contacts.
Thanks.
You should read up on the concept of CancellationTokens. That's the idea you're looking for. Lots of examples online.
What is "cancellationToken" in the TaskFactory.StartNew() used for?
http://dotnetcodr.com/2014/01/31/suspending-a-task-using-a-cancellationtoken-in-net-c/
CancellationToken/CancellationTokenSource is C#'s way of managing and cancelling Tasks.
In your case, you would create a CancellationTokenSource, and pass its Token object in your ContactManager.RequestStoreAsync(CancellationToken token) and contactStore.FindContactsAsync(CancellationToken token) methods (any async methods where you're awaiting).
Those two methods should accept a CancellationToken, and sporadically do a token.ThrowIfCancellationRequested().
If at some point you find that you want to stop the current Task and start a new one (for your case, when the user types something new), call CancellationTokenSource.Cancel(), which will kill the running Task thread because of the ThrowIfCancellationRequested().
One thing I want to point out though, is that your code can be optimized even further before going through CancellationTokens. You call ContactStore contactStore = await ContactManager.RequestStoreAsync(); every time. Could you not store that as a member variable?
You can also do tricks such as not running your load contacts method unless the user has stopped typing for 1 second, and I would suggest that you force concurrent Task execution in this case by using a ConcurrentExclusiveSchedular.

Pros & cons bean vs SSJS?

I was trying to build a bean that always retrieves the same document ( a counter document), gets the current value, increment it and save the document with the new value. Finally it should return the value to the calling method and that would get me a new sequential number in my Xpage.
Since the Domino objects cannot be serialized or singleton'ed what's the benefit creating a bean doing this, over creating a SSJS function doing the exact same thing?
My bean must have calls to session, database, view and document, which then will be called every time.
The same within the SSJS-function except for session and database.
Bean:
public double getTransNo() {
try {
Session session = ExtLibUtil.getCurrentSession();
Database db = session.getCurrentDatabase();
View view = db.getView("vCount");
view.refresh();
doc = view.getFirstDocument();
transNo = doc.getItemValueDouble("count");
doc.replaceItemValue("count", ++transNo);
doc.save();
doc.recycle();
view.recycle();
} catch (NotesException e) {
e.printStackTrace();
}
return transNo;
}
SSJS:
function getTransNo() {
var view:NotesView = database.getView("vCount");
var doc:NotesDocument = view.getFirstDocument();
var transNo = doc.getItemValueDouble("count");
doc.replaceItemValue("count", ++transNo);
doc.save();
doc.recycle();
view.recycle();
return transNo;
}
Thank you
Both pieces of code are not good (sorry to be blunt).
If you have one document in your view, you don't need a view refresh which might be queued behind a refresh on another view and be very slow. Presumably you are talking about a single sever solution (since replication of the counter document would for sure lead to conflicts).
What you do in XPages is to create a Java class and declare it as application bean:
public class SequenceGenerator {
// Error handling is missing in this class
private double sequence = 0;
private String docID;
public SequenceGenerator() {
// Here you load from the document
Session session = ExtLibUtil.getCurrentSession();
Database db = session.getCurrentDatabase();
View view = db.getView("vCount");
doc = view.getFirstDocument();
this.sequence = doc.getItemValueDouble("count");
this.docID = doc.getUniversalId();
Utils.shred(doc, view); //Shred currenDatabase isn't a good idea
}
public synchronized double getNextSequence() {
return this.updateSequence();
}
private double updateSequence() {
this.sequence++;
// If speed if of essence I would spin out a new thread here
Session session = ExtLibUtil.getCurrentSession();
Database db = session.getCurrentDatabase();
doc = db.getDocumentByUnid(this.docID);
doc.ReplaceItemValue("count", this.sequence);
doc.save(true,true);
Utils.shred(doc);
// End of the candidate for a thread
return this.sequence;
}
}
The problem for the SSJS code: what happens if 2 users hit that together? At least you need to use synchronized there too. Using a bean makes it accessible in EL too (you need to watch out not to call it too often). Also in Java you can defer the writing back to a different thread - or not write it back at all and in your class initialization code read the view with the actual documents and pick the value from there.
Update: Utils is a class with static methods:
/**
* Get rid of all Notes objects
*
* #param morituri = the one designated to die, read your Caesar!
*/
public static void shred(Base... morituri) {
for (Base obsoleteObject : morituri) {
if (obsoleteObject != null) {
try {
obsoleteObject.recycle();
} catch (NotesException e) {
// We don't care we want go get
// rid of it anyway
} finally {
obsoleteObject = null;
}
}
}
}

Windows 8 Metro App MediaElement.SetSource (can not change the volume during playback)

I am making Windows 8 Metro style app.
I want to be able to run different sounds at the same time and manage them. For this goals I have created MediaPlayService which should contain methods which allow me to do that.
I found one issue that after "_mediaElement.SetSource()" I can not change volume. I am calling SetVolume and nothing happen.
Initialize(sound);
SetVolume(100);
Play(); --- this sequence works
Initialize(sound);
Play();
SetVolume(100); --- does not work (I can not change the volume during playback)
public void SetVolume(int volume)
{
//_m ediaElement.Volume = Math.Round((double)((double)volume / 100), 2);
double dvolume = Math.Round((double)((double)volume / 100), 2);
_mediaElement.SetValue(MediaElement.VolumeProperty, dvolume);
}
string _mediaPath;
public void Initialize(Sound sound)
{
_mediaElement = new MediaElement();
_mediaPath = sound.FilePath;
_mediaElement.AudioCategory = Windows.UI.Xaml.Media.AudioCategory.Communications;
_mediaElement.IsLooping = true;
_mediaElement.MediaFailed += _mediaElement_MediaFailed;
_mediaElement.RealTimePlayback = true;
}
public async void Play()
{
var pack = Windows.ApplicationModel.Package.Current;
var installedLoction = pack.InstalledLocation;
var storageFile = await installedLoction.GetFileAsync(_mediaPath);
if (storageFile != null)
{
var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
_mediaElement.SetSource(stream, storageFile.ContentType);
_mediaElement.Play();
}
}
Your MediaElement isn't part of the VisualTree of your page. As consequence you have to deal with those strange behaviors like setting the volume or position won't work correctly.
As solution you might create the MediaElement in your XAML file or add it from your code-behind to the VisualTree (something like contentGrid.Children.Add( _mediaElement ). In the latter case you probably have to remove it before navigating to another page else it might happen that it won't play the next time you are navigating back.