Get the teamproject collection from a WorkItem - c#

I want to add the WebPageControl to a WorkItemType and need to define the Teamproject collection of the current Work Item as a path parameter of the URL. The WebPageControle shows a C# Webapplication. Is there a field like System.Teamproject or an other way that gives me the Teamproject collection? I know that the ID of the Work Item isn't unique to all collections and the area path includes only the Project but not the collection.

I don't believe there is a field you can pass along to the page being called, but since the Process Template configuration is stored at the project level, you can customize the work item type definition and simply hard-code the uri to the project collection in the WebpageControl's properties.
There's also the option to update the process template before registering it to the Project Collection. Since each project collection has it's own Template library, you only need to update it when you update the template at the collection level in that case.
This is unfortunately something you'll have to do each time you create a new project or update a process template of an existing Team project. It should not be terribly hard to script though...

If you already have a WorkItem object then you can do wi.Store.[Collection].xxx.
Once you have the store you can get all of the data.

Related

Storing the state of a VSTO Outlook plugin with a draft message

I'm working on a VSTO plugin for Outlook (C#) and find nothing about saving or embedding the state/options of my plugin with a draft message.
Is there any mean to do that ?
Ex: if my plugin makes the message to be displayed in red, I want to have my draft re-opened written in red.
Any idea ?
Use the UserProperties.Add method which creates a new user property in the UserProperties collection. Use the UserProperties property to return the UserProperties object for an Outlook item. This applies to all Outlook items except for the NoteItem.
Use the Add method to create a new UserProperty for an item and add it to the UserProperties object. The Add method allows you to specify a name and type for the new property. When you create a new property, it can also be added as a custom field to the folder that contains the item (using the same name as the property) by setting the AddToFolderFields parameter to true when calling the Add method. That field can then be used as a column in folder views.
To set for the first time a property created by the UserProperties.Add method, use the UserProperty.Value property instead of the SetProperties and SetProperty methods of the PropertyAccessor object.
If you need to keep the data for the folder or Outlook account in general (not per item) you may consider the StorageItem instead. That is a message object in MAPI that is always saved as a hidden item in the parent folder and stores private data for Outlook solutions.
The Outlook object model does not provide any collection object for StorageItem objects. However, you can use Folder.GetTable to obtain a Table with all the hidden items in a Folder, when you specify the TableContents parameter as olHiddenItems. If keeping your data private is of a high concern, you should encrypt the data before storing it.
As Eugene advised, you can use MailItem.UserProperties collection to set/read your custom properties.
A couple points to consider - since named properties are a finite resource, you can have at most 32k of them per mailbox. Once you go over, the mailbox is pretty much dead. So use as few unique properties as possible, and definitely do not use anything dynamic, such as the message subject in the property name.
If you set a user property on an outgoing message, Outlook might force it to go out in the TNEF format. To prevent that from happening, set the property value using MailItem.PropertyAccessor.SetProperty. You can use the same DASL property name that your user property uses, but the point is to avoid using the UserPropeties collection. You can see the DASL property name in OutlookSpy (I am its author) - select a message with your user property set, click IMessage button, select your property, see the DASL edit box.

How to update and add objects to a dynamically nested JSON?

I have a class which contains a list of its instances of the same class. This can get pretty nested and is fairly dynamic. This class has other members and therefore you can have many different cases / setups with different type of nestings.
I am trying to save it as JSON and deserialize when I need to access data.
Serializing is easy since it successfully navigates through the nesting and generates the appropriate jsons.
I am having trouble with updating. So when the session starts, I deserialize the json data that I have, I use this data when needed as a reference to load saved settings when certain elements are created.
My problem is when I want to add a new entry to the json or make updates.
To make updates, I can recursively loop through and find the item and make modifications it it but adding a new item is where I am having difficulty.
Say a few nestings down the line, I have added a new item, How can I add this to the saved JSON in the appropriate spot?
I would post my code but it spans several classes and I would need to post a lot of code.
Essentially, I have a root class and then subclasses of the same type added as children to the list and other items.
How do I determine where in the nestings the new item belongs?
I can find specific items by recursively seraching every branch for its unique ID and make edits to that item to update it but not sure how to dynamically add a new item to specific places throughout the nesting.
When first run, I just take the settings the user sets and store it as JSON.
Next time, when it is run, I deserialize the data I have and store it.
Based on what the user selects, I will load from the above step the settings for any item he selects.
If the user adds a new item, somewhere through the nestings, I need to be able to determine where, then I need to combine both the old JSON and the new JSON (ovveride old values and add new elements if any) then serialize and write to file.
I can't just serialize the new data and store it because then it would be missing the old data if it was not created in this session.
It is kind of confusing but hopefully I have been helpful enough.
Thanks

Unique identifier for Interop.ListObject from VSTO - C#

I need a way to insert (or use an already implemented property that could serve as) a unique identifier into a Microsoft.Office.Interop.Excel.ListObject instance.
The problem is that when I'm creating a new ListObject as:
var excelTable = worksheet.ListObjects.Add(ExcelInterop.XlListObjectSourceType.xlSrcExternal, DUMMY_CONNECTIONSTRING, false, true, cellRange);
I cannot rely on the Name property of excelTable to browse for it in the collection since the user could change the value of that property anytime afterwards.
After browsing trough the object properties I found nothing I could use out of the box (like a Tag property for example, which exists in a Microsoft.Office.Tools.Excel.ListObjecttype of object I cannot use at this point due to dependencies) ...and other weird stuff like a DisplayName that appears not only unable to be set directly but also to reflect the exact same value that the Name property has at all times (Why would you want to have 2 properties that reflect the same value at any time?).
I've thought on either creating my own implementation of this class or probably use the Comment property to store a GUID (which I don't know why kinda feels wrong):
excelTable.Comment = Guid.NewGuid().ToString();
Can you suggest of another way to accomplish this task?
Thanks a lot!
It is quite frustrating that there is no "Tag" (or similar) property that you could set on Excel objects. I'm facing the same issues as you. Here are two options that you can use:
alternative text property (for the table it is only visible by right clicking the table, selecting table and alternative text). This is probably a bit cleaner than Comment since the UI for comment is always visible.
you could also generate a wrapper object that contains a direct reference to the ListObject. So one wrapper object for each created ListObject. This works fine until you save / open the workbook again. If you need to be able to identify the table again after reopening the workbook you would still need to write some id to Comment or Alternative text. You could probably do a clean implementation by using events like BeforeSave and AfterSave (add alternative text before save so it saves to disk, then remove it again after save so that the user doesn't see it. When the workbook opens you load up your wrapper objects and remove the alternative text).

MEF update exported part metadata (the metadata view is invalid because property has a property set method)

I have an application and I'm using MEF to compose it. I want to know if it is possible to update the Metadata information of the parts after they were imported.
The reason to do this is the following: I display the imported parts' name and an typeof(int) property in a ListBox, and they are not loaded until the corresponding ListBoxItem is selected (pretty standard). Now I want to update the Metadata info of one part when some event raises, so the displayed info in the ListBox is somethind like "[Part name] ([new number])".
I'm importing the metadata as an Interface that defines it's info, but when I set the int property to be editable (with a set accesor) I receive the following execption at composition time:
"The MetadataView 'myMetadataInterface' is invalid
because property 'myInt' has a property set method."
Is there ANY way to achieve this? Or is the metadata ALWAYS read only once the part is created?
I know this question looks weird, but it doesn't make it any less difficult and therefore interesting ;-)
EDIT (based on Lee's answer, in order to keep people to the core of the question)
I just want to know if it is possible to update a Metadata property after the part is composed, but before it is actually loaded (HasValue == false). Don't worry about filtering or finding the part.
I added a property to the export inteface, which is meant only to be represented in the UI and to be updated, this property has no other function and the parts are not filtered by it.
Thanks
Metadata filtering and DefaultValueAttribute
When you specifiy a metadata view, an implicit filtering will occur to
match only those exports which contain the metadata properties defined
in the view. You can specify on the metadata view that a property is
not required, by using the
System.ComponentModel.DefaultValueAttribute. Below you can see where
we have specified a default value of false on IsSecure. This means if
a part exports IMessageSender, but does not supply IsSecure metadata,
then it will still be matched.
citation
Short Version (EDITED in after question edit).
You shouldn't ever need to update metadata at runtime. If you have some data that should be updated and belongs to a mef part, you need to choose to either have it be updated by recompiling, or store that data in a flexible storage outside of the dll. There's no way to store the change you made in the dll without recompiling, so this is a flawed design.
Previous post.
Altering values on the view would by lying about the components loaded. Sure the metadata is just an interface to an object that returns initialized values; sure you can technically update those values, but that's not the purpose of metadata.
You wouldn't be changing the Name field of an instance of Type. Why not? Because it's metadata. Updating metadata at runtime would imply that the nature of the instance of real data is somehow modified.
This line of code, if possible, wouldn't introduce the Triple type.
typeof(Double).Name = "Triple";
var IGotATriple = new Triple();
If you want to alter values, you need to just make another object with that information and bind to that. Metadata is compiled in. If you change it after a part is loaded, it doesn't change anything in the part's source, so you'd be lying. (unless you're going to have access to the source-code and you change it there and recompile).
Let's look at an example:
[Export(typeof(IPart))]
[ExportMetadata("Part Name","Gearbox")]
[ExportMetadata("Part Number","123")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class GearBoxPart : Part { public double GearRatio ... }
Now, let's assume that you had a UI that showed available parts and their numbers. Now, the manufacturer changes the part number for whatever reason and you want to update it. If this is possible, you might want to consider storing part number in a manifest or database instead. Alternatively you'd have to recompile every time a part number changes.
Recompile is possible. You have a controller UI that does the above, but instead of updating the metadata, you submit a request to rebuild the part's codefile. The request would be handled by parsing the codefile, replacing the part number, then sending off for a batch recompile and redistribute the new dll. That's a lot of work for nothing IMO.
So, you setup a database. Then you change the object metadata to this.
[ExportMetadata("OurCompanyNamePartNumber","123")]
Then you have a database/manifest/xml that maps your unique permanent static part number that your company devises to the current part number. Modifications in your control UI update the database/manifest/xml.
<PartMap>
<PartMapEntry OurCompanyNamePartNumber="123" ManufacturerPartNumber="456"/>
...
</PartMap>
Then the end-user UI does lookups for the part by manufacturer part number, and the mef code looks in the PartMap to get the mef part number.

Save value of custom field type

I am new to SharePoint developement and have a few startup problems which I hope you will help me with.
I am trying to make a custom field type and I am using WPS builder to create the project. Right now I have the following files which are all compiling just fine :)
SuperLookup3.cs
SuperLookup3Control.cs
SuperLookup3FieldEditor.cs
SuperLookup3FieldEditor.ascx (controltemplate)
fldtypes_SuperLookup3.xml (XML)
I have tried look at this example but I just can't get it to work.
My questions
How is the relationsships between the files?
I can see an override of UpdateFieldValueInItem() which is setting the value to the selected item of a dropdown list. But this method is never called (when debugging). How can this be?
Some general advice would be to post this question to the SharePoint Stack Exchange site (if this answer is unsatisfactory), since there are a lot more SharePoint developers there.
From what I understand of that example, it seems to be quite a complex Custom Field Type to start with (given that it has multiple values). There's a good straightforward and pretty well explained tutorial on MSDN that you might want to try out: Walkthrough: Creating a Custom Field Type
Here's a brief explanation of your files (and the classes they contain):
This is the main class of your field, which derives from the SharePoint field base class (SPField). Your naming seems to indicate you're creating a lookup derivative; if so, you may wish to derived from SPFieldLookup.
This is the class the creates the form control displayed on a list item's New, Edit, and Display forms (but not the List View). It's a go-between for the forms and the item's value for this field.
&
This is the section displayed on the Add/Edit Column page. I would expect 3. to have the ending '.ascx.cs' instead of '.cs', since it is the code-behind for 4.; which may be the cause of your problem. This control sets up your field; associating the class in 1. to the list.
This is the field declaration. It says to SharePoint "Hey, I've created my own field; go look here to find it.", and directs SharePoint to the class in 1., which makes the field available on the Add Column page.

Categories