How to remove a specific ItemProperty from AppointmentItem.ItemProperties - outlook

I use the following method to a new OutlookUserProperty to an AppointmentItem:
MyID = (Outlook.UserProperty)myAppointment.ItemProperties.Add("MyID", Outlook.OlUserPropertyType.olText, false, 1);
... later I want to remove exactly this "MyID" from the ItemProperties collection.
Obviously I can only remove an item from the ItemProperties collection using the
myAppointment.ItemProperties.Remove(index).`
Unfortunately I don't know the index of the element "MyID", and I cannot find any method for retrieving the index of "MyID".

I think you can use UserProperty.Delete to delete your ItemProperty.
UserProperty up = myMailItem.UserProperties["ParentMailRecipients"];
if(up != null)
up.Delete();
More info about: UserProperty
Reference: outlook 2007 addin : How to remove particular userproperty of mailItem
Hope it works for you.

Use PropertyAccessor.DeleteProperty.
To figure out the DASL property name, take a look at the item with OutlookSpy (I am its author - click IMessage button, select the property, look at the DASL property editor).

Related

How to get selected records under bulk edit functionality

I am working on 2016 on-premise MSCRM, I need to check each record in bulk edit and alert the user if something is wrong, I tried to alert it from my update plugin but only general msg appeared, now I'm trying to get all records selected in bulk edit, I googled and found this code :
var formType = Xrm.Page.ui.getFormType();
if (formType == 6)
{
//Read ids from dialog arguments
var records = window.dialogArguments;
}
}
To use the bulk edit formtype I need to add to event onload or onchange on customizations.xml the attribute : BehaviorInBulkEditForm=“Enabled“ (unfortunately not so safe to edit this file) .
My questions:
which selected rows I'll get in onload and onchange event? ,I'm not sure where to use it in that case and if I'll get all the data I need.
Is there a better way/easy to get the data I need or to get the formtype - bulk edit.
Soon I'll be using MSCRM 365 is there any easier solution to this case in the 9.0 version ?
You can use method window.getDialogArguments(); to get ids.
Here is my example:
I added an onLoad event for my form and enabled the BehaviorInBulkEditForm.
function onLoad(formContext) {
var ids = window.getDialogArguments();
console.log(ids);
}
The ids is an array, every element is a selected record id.
['{335A56B7-C717-ED11-B83F-00224856D931}', '{CBBDEBFB-C717-ED11-B83F-00224856D931}', '{3607EFC7-C717-ED11-B83F-00224856D931}', '{325A56B7-C717-ED11-B83F-00224856D931}']

Display Methods - Multiple Form Data Sources

This may seem a simple question, but for some reason I am vexed.
I have a form with 3 datasources - InventTable, InventSum, InventDim.
So, for example, my grid shows;
Item, Name, Site, Warehouse, Physical Stock
I have placed a display method on InventDim form DataSource, but I need access to the ItemId from either inventTrans or InventSum. (Obviously looking for the "current" itemId).
All I can access is the inventDim which is passed as a parameter _inventDim, as standard.
What is the best way to access the "current" itemId?
Okay, I found the answer, with great thanks to this reference by Joris de Gruyter;
http://daxmusings.blogspot.co.uk/2011/10/forum-advanced-display-method-querying.html
The key was to put the display method on the InventSum datasource.
You can then use _inventSum.joinChild() to retrieve the linked inventDim, here is Joris' example;
display Qty AvailPhysical(InventSum _inventSum)
{
InventDim joinDim, dimValues;
InventDimParm dimParm;
InventSum localSum;
//THE IMPORTANT LINE...
dimValues.data(_inventSum.joinChild());
dimParm.initFromInventDim(dimValues);
select sum(AvailPhysical) from localSum where localSum.ItemId == _inventSum.ItemId
#InventDimExistsJoin(localSum.InventDimId, joinDim, dimValues, dimParm);
return localSum.AvailPhysical;
}
I am sure this will help someone out in the future!

WatiN SelectList - How can I select any element from the list?

I'm using WatiN to do some web testing and have run into a problem with a select list.
I have to run through a few pages first, adding a 'Category' element that will populate said troublesome select list.
I have been able to easily select an element from the list using ByValue, but the problem here is that the values is more of an index element that is created on the fly with a seemingly random value when the 'Category' element is created. I have tried to use the text that is under the option list in the html but it cannot seem to find it.
At this point I'm willing to settle for any element in the list that isn't value "-1" as this is the "Please select an option item".
Any help at all would be appreciated,
Thanks in advance
Keith 8o8
If i understand correctly maybe this can help:
OptionCollection options = browser.SelectList("elementId").Options;
options[0].Select();
Here is a solution :
SelectList list = _browser.Frame(Find.ById(frameId)).SelectList(listId);
foreach (Option tempOption in list.Options)
{
string value = tempOption.Text;
if (!string.IsNullOrEmpty(value)) // Compare with visible option text
{
if (value.Equals(option))
{
list.Option(option).Select();
found = true;

Error when I try to read/update the .Body of a Task via EWS Managed API - "You must load or assign this property before you can read its value."

I am using the Exchange Web Services Managed API to work with Tasks (Exchange 2007 SP1). I can create them fine. However, when I try to do updates, it works for all of the fields except for the .Body field. Whenever I try to access (read/update) that field, it gives the following error:
"You must load or assign this property before you can read its value."
The code I am using looks like this:
//impersonate the person whose tasks you want to read
Me.Impersonate(userName); //home-made function to handle impersonation
//build the search filter
Exchange.SearchFilter.SearchFilterCollection filter = New Exchange.SearchFilter.SearchFilterCollection();
filter.Add(New Exchange.SearchFilter.IsEqualTo(Exchange.TaskSchema.Categories, "Sales"));
//do the search
EWS.Task exTask = esb.FindItems(Exchange.WellKnownFolderName.Tasks, filter, New Exchange.ItemView(Integer.MaxValue));
exTask.Subject = txtSubject.Text; //this works fine
exTask.Body = txtBody.Text; //This one gives the error implying that the object isn't loaded
The strange thing is that, inspecting the property bag shows that the object contains 33 properties, but {Body} is not one of them. That property seems to be inherited from the base class .Item, or something.
So, do I need to re-load the object as type Item? Or reload it via .Bind or something? Keep in mind that I need to do this with thousands of items, so efficiency does matter to me.
Calling the Load method solved my problem :)
foreach (Item item in findResults.Items)
{
item.Load();
string subject = item.Subject;
string mailMessage = item.Body;
}
I had the same problem when using the EWS. My Code is requesting the events(Appointments) from the
Outlook calendar, at the end I couldn't reach to the body of the Event itself.
The missing point in my situation was the following "forgive me if there is any typo errors":
After gathering the Appointments, which are also derived from EWS Item Class, I did the following:
1- Create a List with the type Item:
List<Item> items = new List<Item>();
2- Added all appointments to items list:
if(oAppointmentList.Items.Count > 0) // Prevent the exception
{
foreach( Appointment app in oAppointmentList)
{
items.Add(app);
}
}
3- Used the exchanged service "I have already created and used":
oExchangeService.LoadPropertiesForItems(items, PropertySet.FirstClassProperties);
now if you try to use app.Body.Text, it will return it successfully.
Enjoy Coding and Best Luck
I forgot to mention the resource:
http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/ce1e0527-e2db-490d-817e-83f586fb1b44
He mentioned the use of Linq to save the intermediate step, it will help you avoid using the List items and save some memory!
RockmanX
You can load properties using a custom property set. Some properties are Extended properties instead of FirstClassProperties.
Little example:
_customPropertySet = new PropertySet(BasePropertySet.FirstClassProperties, AppointmentSchema.MyResponseType, AppointmentSchema.IsMeeting, AppointmentSchema.ICalUid);
_customPropertySet.RequestedBodyType = BodyType.Text;
appointment.Load(_customPropertySet);

best practice Treeview populating from differents kinds of objects

I would like to populate a Treeview.
Here is what I have in DB :
table : Box
BoxID
BoxName
table Book :
BookID
BookName
BoxID (fk Box.BoxID)
table Chapter:
ChapterID
ChapterName
BookID (fk Book.BookID)
As you may know a treeview is made up of treenode object.
A treenode object have a text property and a tag property.
The "text" property is the text that it's display on the screen for this node and the "tag" is an "hidden" value (usually uses to identify a node)
So in my case; the fields ending with ID will be used in the "tag" property and the fields ending with Name will be used in the "text" property
example :
so for a book; I will use the BookID field for the "tag" property and BookName field for the "text" property
note : I use a dbml so I have a Book object, Box object and Chapter object and I use linq to get them from the db.
So my question is; what is the best practice to build this tree?
I have a solution but it's really ugly because it looks like I'm duplicating the code.
The problem is that the values I need to extract for the text and tag properties are identified by differents fields name in the db
So for the book level, I need to get the BookID field to populate the tag property of my node; for the box level, I need to get the BoxID field to populate the tag property , ....
How can I make a kind of generic way to do it ?
I hope I made myself clear enough, don't hesitate to ask me questions :)
Thx in advance
Here is what I have for the moment
I get the list of box with a linq (dbml) request.
List<Box> MyListofBox = getMyListofBox();
Treenode tnBox = null;
Treenode tnBook =null;
foreach(Box b in MyListofBox )
{
tnBox = new TreeNode();
tnBox.tag = b.BoxID;
tnBox.text = b.BoxName;
List<Book> MyListofBook = getMyListofBookByBoxID(b.BoxID)
foreach(Book boo in MyListofBook )
{
tnBook = new TreeNode();
tnBook.tag = boo.BookID;
tnBook.text = boo.BookName;
tnBox.nodes.add(tnBook);
}
mytreeview.nodes.add(tnBox);
}
but of course I don't like this solution...
do you have a better way ?
I would extract the you need from the database in the form of a struct, possibly via the anonnoumous type that has been added to C# together with linq. Then I would populate insert this data into the place in the tree.
From what I get, you are trying to get each property separately, which will not work so well, because then you will have to make a call to the database for each separate property, which is very wasteful.
Addition based on what you have added
I do not believe the code can be more compact - the names you call are similar, but not the same and the way you do it was what I was trying to explain earlier.
You could
Define an key/value interface that both Box and Book implement
Define a delegate that returns a TreeNode and create delegate methods that accept Box and Book
However, I think the code is fine as written. Sometimes you just have to code it and there's little point in further abstracting or optimizing it.
The only issue I see in the code is that you're making a database call in a loop. Whether or not that's a problem depends on the application.

Resources