Mango Application Tile - remove back - tile

This is a simple question, and a seemingly simple task but I can't find any info on how to accomplish what I need to do.
I have an application whose main tile (when pinned) sometimes needs to be the default, single sided tile and sometimes needs to have information displayed on the back of the tile. I can add the BackBackgroundImage, BackContent and BackTitle successfully from the ScheduledActionService, but I can't remove them when they are no longer required. This isn't a secondary tile so I can't remove it and re-create and re-add it.
Does anyone know if it is possible to revert a double-sided tile back to single-sided via code, and if so, how can I achieve that behaviour, please?
EDIT
The settings that get applied from the StandardTileData object are additive - if you only specify a title, for example, all other elements remain the same and only the title is updated. I have attempted to set the three parameters that appear on the back of the tile to null and had partial success. The effect is that the background image, title text and content text are all removed, but the tile still flips over to show a completely empty reverse side.
EDIT AGAIN
So, looking at the documentation, the tile back behaves differently to the front. Setting the back content or backtitle to string.Empty will remove those. All good there. However, it does say that "If set to an empty URI, the BackBackgroundImage will not be displayed.". How do I go about creating an empty Uri? I tried new Uri(string,Empty) but that throws an exception about trying to create an empty Uri - which is what I'm trying to do.

OK, I think I've got it, and it appears to be related to a change in the way tile data is handled...
Previously, setting a value to an empty string would have now effect in the tile. For eaxmple, setting title = string.Empty would leave the existing title in place. Now, though, it will blank out the title. That's good - it means I can remove BackTitle and BackContent string easily. We're half way there.
Now, to get rid of the BackBackgroundImage, the documentation states "If set to an empty URI, the BackBackgroundImage will not be displayed." - all good, except you can't create an empty Uri in any simple way. The one way I've made it work is to set it to a Uri value that doesn't exist, eg
BackBackgroundImage = new Uri("obviouslyMadeUpLocation", UriKind.Relative);
I would have expected that to throw an exception when you try to apply it to the tile, but it doesn't - it just clears the background image.
So that's it. All I appear to need to do is to call the following to unset these properties and put my tile back as it was.
private void ResetMyMainTile()
{
ShellTile tile = ShellTile.ActiveTiles.First();
StandardTileData data = new StandardTileData
{
BackBackgroundImage = new Uri("IDontExist",UriKind.Relative),
BackContent = string.Empty,
BackTitle = string.Empty
};
tile.Update(data);
}

This one works for me.
new Uri("Background.png", UriKind.RelativeOrAbsolute);
ShellTile TileToFind = ShellTile.ActiveTiles.First();
if (TileToFind != null)
{
StandardTileData NewTileData = new StandardTileData
{
Title ="Status",
BackgroundImage = new Uri("Background.png", UriKind.RelativeOrAbsolute),
Count = 0,
BackTitle = "",
BackBackgroundImage = new Uri("doesntexist.png", UriKind.RelativeOrAbsolute),
BackContent = ""
};
TileToFind.Update(NewTileData);
}

Try setting the whole tile (all details) again to everything as was before / is now but without the background details.
Update
Does this not work?:
ShellTile tile = ShellTile.ActiveTiles.First();
tile.Update(null);
or
tile.update(new StandardTileData());

Related

Set PurchReqLine.BuyingLegalEntity default value to blank

I encountered a problem in the development, requesting a new purchase request line of a purchase with a legal person with a default value of empty
I tried a variety of methods, the default value can not be overriden.
The following is my code.
[ExtensionOf(formDataSourceStr(PurchReqTable, PurchReqLine))]
final class IWS_PurchReqTable_FDS_Extension
{
public void initValue()
{
next initValue();
//ttsbegin;
PurchReqLine purchReqLine = this.cursor();
purchReqLine.BuyingLegalEntity = 0;
purchReqLine.modifiedField(fieldNum(PurchReqLine,BuyingLegalEntity));
this.rereadReferenceDataSources(); //Refresh value
this.reread();
this.research(1);
FormReferenceGroupControl BuyingLegalEntity = this.formRun().design().controlName(formControlStr(PurchReqTable, PurchReqLine_BuyingLegalEntity));
FormStringControl BuyingLegalEntity_DataArea = this.formRun().design().controlName(formControlStr(PurchReqTable, PurchReqLine_BuyingLegalEntity_DataArea));
BuyingLegalEntity.value(0);
BuyingLegalEntity.resolveChanges();
BuyingLegalEntity.referenceDataSource().research(1);
BuyingLegalEntity.modified();
//BuyingLegalEntity_DataArea.text('');
//BuyingLegalEntity_DataArea.modified();
purchReqLine.BuyingLegalEntity = 0;
purchReqLine.modifiedField(fieldNum(PurchReqLine,BuyingLegalEntity));
//purchReqLine.update();
//purchReqLine.insert();
//this.rereadReferenceDataSources();
//this.refresh();
//this.reread();
//this.resetLine();
//ttscommit;
}
//End
}
It is not totally clear to me what you are trying to do.
Most values are "born" zero or blank and if that is not the case for this field, something else is setting the field, maybe after your code in initValue is called. The cross reference may be of good value here to find the code that references the field.
First of, you should definitely not reference the controls, also calling modifiedField and research from here is a total no-go.
For a start try this:
public void initValue()
{
next initValue();
purchReqLine.BuyingLegalEntity = 0;
}
It simply sets the field to zero. Do not worry about the field control, it will be rendered from the buffer value after the call to initValue.
If that does not solve your problem, something else is setting the field. You can set a breakpoint here, then follow to code until the field is set. Also add the value to the watch list, maybe do conditional debugging.
If another extension for this datasource exist it may override your behaviour as the execution order of extensions is arbitrary.

Image won't display when using session in .NET

I am working with a session and I want to display image when choosing it from a gridview, so what I have two gridviews the first contain the rows from the database the second should contain the rows chosen from the first one the issue that I have is the first display image with no problem but the second won't show up any.
This is my code for the first one
foreach (CONTENT c in ls)
{
string ext = Helper_GetExtensionFromMimeType(c.MimeType);
c.TmpFilename = string.Format("~/Images/Contents/Content-{0}{1}", c.ContentID, ext);
}
gridview1.DataSource = ls;
gridview1.DataBind();
The code for the second one is (the session name is panier)
CONTENT dummy;
dummy = new CONTENT();
dummy.TmpFilename = Server.MapPath(string.Format("~/Images/Contents/Content-{0}{1}",
c.ContentID, ext));
panier.Add(dummy);
gridview2.DataSource = panier;
gridview2.DataBind();
It will be hard to determine what the issue exactly is without seeing your view code.
Anyway, make sure the image indeed exists in the generated location.
Place a breakpoint after the line dummy.TmpFilename and ensure the link is indeed formatted with the correct c.ContentID and ext, then copy the link to the browser making sure the image exists.
i found a solution to the probleme and here it is if anyone is interested
i replace
dummy.TmpFilename = Server.MapPath(string.Format("~/Images/Contents/Content-{0}{1}",c.ContentID, ext));
with
dummy.TmpFilename =string.Format("~/Images/Contents/Content-{0}{1}",c.ContentID, ext);

Is there a way to access ALAssets information outside of resultBlock?

Okay so I have my ImagePicker all setup and the ALAssetLibrary setup to get the Picture and Title (if it exists for existing pictures or generic text for a new picture) but now I'm trying to figure out if there's a way I can access this information outside of the block call from the assetForURL method. So here's my code just so I can show what's happening (this is in the viewDidLoad method of a screen that is displayed after a picture selection is made)
__block NSString *documentName;
__block UIImage *docImage;
NSURL *resourceURL = [imageInfo objectForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *asset)
{
ALAssetRepresentation *imageRep = [asset defaultRepresentation];
//Get Image
CGImageRef iref = [imageRep fullResolutionImage];
//If image is null then it's a new picture from Camera
if (iref == NULL) {
docImage = [imageInfo objectForKey:UIImagePickerControllerOriginalImage];
documentName = #"New Picture";
}
else {
docImage = [UIImage imageWithCGImage:iref];
documentName = [imageRep filename];
}
};
// get the asset library and fetch the asset based on the ref url (pass in block above)
ALAssetsLibrary *imageAsset = [[ALAssetsLibrary alloc] init];
[imageAsset assetForURL:resourceURL resultBlock:resultblock failureBlock:nil];
Now I want to be able to use the two variables (documentName and docImage) elsewhere in this ViewController (for example if someone wants to change the name of the document before they save it I want to be able to revert back to the default name) but I can't seem to figure out what I need to do so these variables can be used later. Don't know if this makes much sense or not, so if I need to clarify anything else let me know.
Okay so I figured out that the problem wasn't with the code but with my logic on how I was using it. I was trying to do this on the Modal View that was presented after an image was selected instead of just doing this in the ImagePicker screen and then calling the Modal window inside of the result block code.

Can I have flexible/catchall regions with Tridion XM/New UI/2012 UI

I am putting together a functional design for a site which will aims use the Tridion 2012 UI/XM to manage pages. There are 2 regions on the page, a main content area on the left and a side-bar on the right. Ideally users should be able to drag and drop content into and within these regions. In an ideal world I would like to define the regions along the lines of
Side Bar: any CP for which the CT has the text 'Right' in it.
Main: all other CPs
Looking at the documentation it seems that you need to explicitly use CT/Schema ID pairs to define regions. Is there any possibility to do this in any other way?
At the very least I would like to be able to define that the side bar allows a certain fixed set of CT/Schema ID pairs, but have the main region as a catchall bucket.. Is this possible?
It is also possible that the Side Bar is split into 2 regions, above and below an advertisement. Both regions should allow the same types of CP - as far as I understand this is not possible - is this correct? Are there any ideas for workarounds?
To configure regions that take all Content Types, You need to get Publication AppData and loop through the content types and build your json markup for enabling this.You could write C# TBB which includes on each page template and does this logic, you can define some metadata at CT level which determines which region it will go in and build the Region JSON markup.
Below is the snippet to get all Component types to add in one region. You could change the logic to get only right just by checking the template name.
// get the publication from the engine -- using TemplateBase Util..
Publication thisPub = GetPublication();
XmlElement seAppdata = thisPub.LoadApplicationData("SiteEdit").GetAs<XmlElement>();
XmlNamespaceManager seNsMgr = new XmlNamespaceManager(new NameTable());
seNsMgr.AddNamespace("se", "http://www.sdltridion.com/2011/SiteEdit");
seNsMgr.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
XmlNodeList contentTypes = (XmlNodeList)seAppdata.SelectNodes("//se:ContentTypes/se:ContentType", seNsMgr);
List<String> contentTypeJson = new List<String>();
foreach (XmlNode contentType in contentTypes)
{
string templateId = contentType.SelectSingleNode("se:ComponentTemplate/#xlink:href", seNsMgr).Value;
string componentId = contentType.SelectSingleNode("se:Component/#xlink:href", seNsMgr).Value;
Component thisSchema = (Component)engine.GetObject(componentId);
string schemaId = thisSchema.Schema.Id;
// Add json formated string for Content Types
contentTypeJson.Add(string.Format("{{schema: \"{0}\", template: \"{1}\"}}", schemaId, templateId));
}
// Final Markup - JSON
String allRegionSeText = string.Format("<!-- Start Region: {{title: \"All Region\", allowedComponentTypes: [{0}], minOccurs: 1, maxOccurs: 5 }} -->", string.Join(",", contentTypeJson.ToArray()));
// Push to the package to use in DWT..
package.PushItem("ALL_REGION", package.CreateStringItem(ContentType.Text, allRegionSeText));
Hope this helps.
Have you tried creating a region without specifying CT/Schema pairs? I remember seeing in an early implementation that you could drop a content type anywhere because regions hadn't been configured properly (or perhaps at all).

Why am I losing my databinding when printing to an XpsDocument?

Update!
Binding works. The issue is that the XpsDocumentWriter doesn't properly write the first page of the first document of a FixedDocumentSequence. This seems to be an issue encountered by lots of people doing this sort of thing (i.e., five developers worldwide). The solution is slightly odd. I include it as an answer.
Okay, its a bit more subtle than the question suggests.
I've got a series of FixedPages, each has its DataContext set individually. Each FixedPage also has one or more controls that are bound to the context.
If I add these FixedPages to a single FixedDocument and write this single FixedDocument to an XpsDocument, my binds are de-referenced (so to speak) and the correct values are presented in the XpsDocument.
If I add these FixedPages to individual FixedDocuments (each FP gets added to a new FD), then these FixedDocuments are added to a FixedDocumentSequence, and this sequence is then written to the XpsDocument, my binds are NOT de-referenced and my FixedPages appear blank.
Debugging tells me that I'm not losing my bindings or my binding context, so that's not the cause of this failure.
Here's some sample code to illustrate what's going on:
// This works
FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
// Add my databound fixed page to a new fixed document
var fd = new FixedDocument();
var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create an xps document and write my fixed document to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fd);
p.Flush();
p.Close();
// This does NOT work
FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
// Add my databound fixed page to a new fixed document
var fd = new FixedDocument();
var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create a fixed document sequence and add the fixed document to it
FixedDocumentSequence fds = CreateFixedDocumentSequence();
var dr = new DocumentReference();
dr.BeginInit();
dr.SetDocument(fd);
dr.EndInit();
(fds as IAddChild).AddChild(dr);
// Create an xps document and write the fixed document sequence to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fds);
p.Flush();
p.Close();
You can see that the only difference between the two is that I'm adding the fixed document to a fixed document sequence, which then gets written.
Obviously, whatever magic happens that causes the databinding to be evaluated and the bound values be inserted isn't happening when my fixed documents aren't being Written to the Xps Document. I need to be able to write more than one fixed document, and the Write method can only be called once, thus requiring I add the FixedDocuments to a FixedDocumentSequence which I then write. But I also need my damn databinding to work as well!
Any help in this situation would be appreciated. I know its not exactly the most common part of the framework; I'm just hoping that someone here has some operational experience with this (I'm looking at you, lurking MS employee).
The cause of this bug is that the FixedPage's layout isn't being updated prior to writing. This causes the first FixedPage in the first FixedDocument in the FixedDocumentSequence to be written incorrectly. This affects NO OTHER PAGES IN THE RESULTING DOCUMENT, which made this bug/edge case harder to nail down.
The following WORKS (rewritten version of the non-working example):
FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
var fd = new FixedDocument();
/* PAY ATTENTION HERE */
// set the page size on our fixed document
fd.DocumentPaginator.PageSize =
new System.Windows.Size()
{
Width = DotsPerInch * PageWidth,
Height = DotsPerInch * PageHeight
};
// Update the layout of our FixedPage
var size = fd.DocumentPaginator.PageSize;
page.Measure(size);
page.Arrange(new Rect(new Point(), size));
page.UpdateLayout();
/* STOP PAYING ATTENTION HERE */
var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create a fixed document sequence and add the fixed document to it
FixedDocumentSequence fds = CreateFixedDocumentSequence();
var dr = new DocumentReference();
dr.BeginInit();
dr.SetDocument(fd);
dr.EndInit();
(fds as IAddChild).AddChild(dr);
// Create an xps document and write the fixed document sequence to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fds);
p.Flush();
p.Close();
I found this issue while trying to use XpsDocumentWriter to write to a PrintQueue. The following code prints the first page correctly.
//Prints correctly
FixedDocumentSequence Documents = new FixedDocumentSequence();
//some code to add DocumentReferences to FixedDocumentSequence
PrintDialog printDialog = new PrintDialog
{
PrintQueue = LocalPrintServer.GetDefaultPrintQueue()
};
printDialog.PrintTicket = printDialog.PrintQueue.DefaultPrintTicket;
if (printDialog.ShowDialog() == true)
{
Documents.PrintTicket = printDialog.PrintTicket;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printDialog.PrintQueue);
writer.Write(Documents, printDialog.PrintTicket);
printerName = printDialog.PrintQueue.FullName;
}
If you remove the printDialog.ShowDialog() and just attempt to silent print to the default printer, the first page prints incorrectly. However, in my scenario, I didn't need to use a FixedDocumentSequence so I swapped it out for just a single FixedDocument and silent printing worked. I tried updating the layout on the FixedPage without success. Weird how the first page prints fine if I show the print dialog though.
One reason that you lose a binding is that you throw an exception somewhere - unfortunately, this exception is silently swallowed and your binding just "stops working". Turn on First-chance exceptions and see if anything gets hit.

Resources