I added an entry in the Properties.Settings named strCol that is of type NameValueCollection. I am using this to save items from a listview to the settings so that when the application reboots, the ListView gets re-populated again with the items that were saved previously. I'm only storing the item name and the tag from the ListViewItems.
But something strange is happening I cant explain.
I am using this code to save the items to the settings:
NameValueCollection nvCol = new NameValueCollection();
foreach (ListViewItem lviP in lvParmNames.Items)
{
nvCol.Add(lviP.Text, lviP.Tag.ToString());
}
Properties.Settings.Default.strCol = nvCol;
Properties.Settings.Default.Save();
For some reason the Save and load in and from settings works fine, as long as the application is still active. But when the application has been closed and rebooted, the load doesn't work as if the NameValueCollection was not saved.
What am I missing here ?
How I'm currently loading the setting:
The call for loading, but it already seem to fail at the check if its null
if (Properties.Settings.Default.strCol != null)
{
NameValueCollection nv = Properties.Settings.Default.strCol;
foreach (string key in nv)
{
try
{
var value = nv[key];
ListViewItem lvi = new ListViewItem(key);
lvi.Tag = value;
lvFamNames.Items.Add(lvi);
}
catch (Exception ex)
{
TaskDialog.Show("Error", "Error while parsing Family Names from saved settings. \n" + ex.Message);
}
}
}
Just noticed something:
Though i added the NameValueCollection in the sections it is actually not added when building the application. When i open the config file, the setting is not there.
So i guess the issue is here, though now i need to figure out how to add it now.
Looking into the Settings.Designer.cs file, i guess this part looks wrong for the type of 'NameValueCollection`:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.Specialized.NameValueCollection strColExcelFamNames {
get {
return ((global::System.Collections.Specialized.NameValueCollection)(this["strCol"]));
}
set {
this["strCol"] = value;
}
}
Related
I am using the PdfSharp reference library to attempt to add functionality to my program that adds metadata tags. I am able to successfully add metadata tags to a document, but I am having an issue with updating the tags on existing custom properties. Whenever I attempt to use my method to update the custom properties, I receive the following exception:
"'System.Collections.Generic.KeyValuePair' does not contain a definition for 'Name'."
Could you guys tell me if I am coding the if statement in the foreach loop below to correctly loop through all of the custom elements in the PDF document to see if it exists and needs to be updated? Thanks.
public void AddMetaDataPDF(string property, string propertyValue, string
path)
{
PdfDocument document = PdfReader.Open(path);
bool propertyFound = false;
try {
dynamic properties = document.Info.Elements;
foreach(dynamic p in properties)
{
//Check to see if the property exists. If it does, update
value.
if(string.Equals(p.Name, property,
StringComparison.InvariantCultureIgnoreCase))
{
document.Info.Elements.SetValue("/" + property, new
PdfString(propertyValue));
}
}
// the property doesn't exist so add it
if(!propertyFound)
{
document.Info.Elements.Add(new KeyValuePair<String, PdfItem>
("/"+ property, new PdfString(propertyValue)));
}
}
catch (Exception ex)
{
MessageBox.Show(path + "\n" + ex.Message);
document.Close();
}
finally
{
if(document != null)
{
document.Save(path);
document.Close();
}
}
}
I didn't try your code but a common issue when working with this library is that you need to add a slash before the name of the property for it to be found. The code below will make the trick.
PdfDocument document = PdfReader.Open(path);
var properties = document.Info.Elements;
if (properties.ContainsKey("/" + propertyName))
{
properties.SetValue("/" + propertyName, new PdfString(propertyValue));
}
else
{
properties.Add(new KeyValuePair<String, PdfItem>("/" + propertyName, new PdfString(propertyValue)));
}
document.Save(path);
document.Close();
Also the PDF file shouldn't be write protected. Otherwise you need to use a tool for unlocking the file before calling PdfSharp.
I've created a Standard SharePoint 2013 Event Receiver on a custom list.
Watched Event = "ItemAdded".
Later in my code I need to retrieve the attachments of the list item in the same order as the user inserted them. But unfortunately it seems that SharePoint does not do this by Default.
Example:
The User creates a list item and attach the following files
Picture_front.jpg
Picture_back.png
Picture_231.jpg
Now in my Event Receiver it is possible that I first get 'Picture_back' then 'Picture_front'... or in any other order.
How can I retrieve the attachments in the same order as they have been attached to the list item?
I tried to use the SPFile Property 'TimeCreated' but this is also not working... They got the same timestamp :( (also if I am using 'Ticks')
Any ideas or I am doing something wrong?
Here is my Code:
public override void ItemAdded(SPItemEventProperties properties)
{
SPAttachmentCollection attachments = properties.ListItem.Attachments;
if (attachments.Count > 0)
{
int p = 1;
Dictionary<string, string> attachementDict = new Dictionary<string, string>();
try
{
foreach (string attachement in attachments)
{
SPFile attachementFile = properties.ListItem.ParentList.ParentWeb.GetFile(properties.ListItem.Attachments.UrlPrefix + attachement);
string imageUrlPath = properties.WebUrl + attachementFile.ServerRelativeUrl;
string imageTimestamp = attachementFile.TimeCreated.Ticks.ToString();
// This Dict is used lator for sorting
// but at the Moment I get here the error that the same key already exists because of the same timestamp of the files :(
attachementDict.Add(imageTimestamp, imageUrlPath);
}
}
catch (Exception ex)
{
// SPLog
}
}
here my code ..i hope it help you!
try
{
string strUrl = SPContext.Current.Site.Url + "/" + subSite;
using (SPSite Site = new SPSite(strUrl))
{
using (SPWeb Web = Site.OpenWeb())
{
SPList List = Web.Lists[listName];
SPListItem item = List.GetItemById(ID);
foreach (String attachmentname in item.Attachments)
{
AnnouncementsCommon objAnnouncementsCommon = new AnnouncementsCommon();
String attachmentAbsoluteURL = item.Attachments.UrlPrefix + attachmentname;
objAnnouncementsCommon.AttachmentName = attachmentname;
objAnnouncementsCommon.AttachmentURL = attachmentAbsoluteURL;
lstAnnouncementsCommon.Add(objAnnouncementsCommon);
}
}
}
}
catch (Exception Exc)
{
Microsoft.Office.Server.Diagnostics.PortalLog.LogString("SSC DAL Exception Occurred: {0} || {1}", Exc.Message, Exc.StackTrace);
}
return lstAnnouncementsCommon;
}
As an alternative approach you could use your receiver to store the attachments in a picture library and add two fields to this library: a lookup column to your original custom list item and an option column with "default", "front view", "back view" (or similar).
One advantage is that you can easily update your images in the future and another is that SharePoint automatically creates two preview miniatures in convenient sizes for your images which allows you to reduce bandwidth.
I have a block of code where I'm trying to disable event firing when editing a file, once the debugger hits the item.SystemUpdate(false) line it throws an exception that states "The file xxxx has been modified by xxxxx"
HandleEventsFiring handle = new HandleEventsFiring();
handle.DisableHandleEventFiring();
try
{
web.AllowUnsafeUpdates = true;
SPFile rptFile = web.GetFile(item.Url); //item is an SPListItem
if (rptFile.Exists)
{
WordDocUtility word = new WordDocUtility();
using (System.IO.Stream stream = rptFile.OpenBinaryStream())
{
word.ReplaceKeys(stream, keys);
rptFile.SaveBinary(stream);
}
}
item.SystemUpdate(false); // the line throwing the exception
}
finally
{
handle.EnableHandleEventFiring();
web.AllowUnsafeUpdates = allowUnsafeUpdates;
}
public class HandleEventsFiring: SPItemEventReceiver
{
public void DisableHandleEventFiring()
{
this.EventFiringEnabled = false;
}
public void EnableHandleEventFiring()
{
this.EventFiringEnabled = true;
}
}
Does anyone know of a way around this or am I doing something wrong?
Any help would be greatly appreciated.
You haven't really shown enough of the code for us to point you to the exact problem. The error that you're getting means that after you pulled the list item that is in item from the content database it was later updated. Chances are, if you get the error every single time, that you're pulling down the same item more than once and your changes are conflicting with yourself. My guess is that item represents a file in a document library, and that you're modifying the file in addition to the splist item. These changes are what are conflicting. You need to fetch the item, update the item, then fetch the file and update the file. If you need to fetch the item and then update the file you will need to fetch the item again so that you don't end up updating an item when another update occurred between the fetch and update.
I'm trying to save a TFS Work Item programmatically but always get the exception:
TF237124: Work Item is not ready to save
Now, I understand what this is telling me - that the Work Item is missing a required field or similar - and my code is anticipating this by calling:
ArrayList ValidationResult = wi.Validate();
before the save. However my ArrayList contains no elements following this call.
I've tried logging in to the TFS web interface using the same credentials and creating a Work Item that way which works fine.
How can I discover why my Work Item won't save? Here's my code:
// get a reference to the team project collection (authenticate as generic service account)
using (var tfs = new TfsTeamProjectCollection(tfsuri, new System.Net.NetworkCredential("My_User", "password")))
{
tfs.EnsureAuthenticated();
var workItemStore = GetWorkItemStore(tfs);
// create a new work item
WorkItem wi = new WorkItem(GetWorkItemType(type, workItemStore));
{
//Values are supplied as a KVP - Field Name/Value
foreach (KeyValuePair<string,string> kvp in values)
{
if (wi.Fields.Contains(kvp.Key))
{
wi.Fields[kvp.Key].Value = kvp.Value;
}
}
ValidationResult = wi.Validate();
}
if (ValidationResult.Count == 0)
{
wi.State = wi.GetNextState("Microsoft.VSTS.Actions.Checkin");
wi.Save();
return wi.Id;
}
else
{
return 0;
}
}
}
You are validating the work item before you are changing it's state. Transitioning to a new state can cause Work Item Template actions/rules to be processed. These could be changing the values of some of your fields and/or adding new rules to the fields which would cause the previously valid data to be invalid.
Moving from an Open state to a Closed state might require someone to complete a "Review" field (for example) - if it's empty it cannot transission.
Try validating after the State change and see if there are any failures.
Ok, I guess I'm having a brain fart here and cant find my way out of it. What I'm trying to accomplish is to list all startup items (applications, processes, etc) and display them on a form (like what you get with msconfig.exe). I thought this code would do it:
private List<StartupItems> getStartupItems()
{
try
{
ManagementClass cls = new ManagementClass("Win32_StartupCommand");
ManagementObjectCollection coll = cls.GetInstances();
List<StartupItems> items = new List<StartupItems>();
foreach (ManagementObject obj in coll)
{
items.Add(
new StartupItems
{
Command = obj["Command"].ToString(),
Description = obj["Description"].ToString(),
Name = obj["Name"].ToString(),
Location = obj["Location"].ToString(),
User = obj["User"].ToString()
});
}
return items;
}
catch (Exception ex)
{
_message = ex.ToString();
_status = false;
return null;
}
But all that gets are the enabled ones with my username. What I'm trying to get is all items, either my username or system, all the enabled ones and all the disabled ones as well (just like msconfig). I've done tons of searching and cannot find anything really any different than what I'm using.
Have you considered reading directly from the registry?
One alternative would be to run autorunssc (it's the command-line version of autoruns) in the background and read its response.