Why this code from Autodesk help doesn't work? - c#

I am trying to run code from the Autodesk help
http://help.autodesk.com/view/RVT/2014/ENU/?guid=GUID-B6FB80F2-7A17-4242-9E95-D6056090E85B
private void CreateViewFilter(Autodesk.Revit.DB.Document doc, View view)
{
List<ElementId> categories = new List<ElementId>();
categories.Add(new ElementId(BuiltInCategory.OST_Walls));
ParameterFilterElement parameterFilterElement =
ParameterFilterElement.Create(doc, "Comments = foo", categories);
FilteredElementCollector parameterCollector = new FilteredElementCollector(doc);
Parameter parameter = parameterCollector.OfClass(typeof(Wall)).FirstElement().get_Parameter("Comments");
List<FilterRule> filterRules = new List<FilterRule>();
filterRules.Add(ParameterFilterRuleFactory.CreateEqualsRule(parameter.Id, "foo", true));
parameterFilterElement.SetRules(filterRules);
OverrideGraphicSettings filterSettings = new OverrideGraphicSettings();
// outline walls in red
filterSettings.SetProjectionLineColor(new Color(255, 0, 0));
view.SetFilterOverrides(parameterFilterElement.Id, filterSettings);
}
When I open a view and run the code more than once, I get the following error
Revit encounterd a argumentException. The given value for name is already in use as a filter element name parmeter name: name at ParameterFilterElement parameterFilterElement = ParameterFilterElement.Create(doc, "Comments= foo", categories). I can't see where this happened in the code.(OBS I change the get_parameter to lookupparameter in the original code above because the first is deprecated)

According to the docs, the second parameter to the Create method is name. The error message states that you are already using the name "Comments = Foo". So I think your best bet is to dynamically generate the name or provide a way for a user to specify the name.

After a little bit thinking I get it. Actually I should do that from the beginging. Anyway the prgram create filter and It is now in the view so when I run the command again there is already one. Thank you.

Related

view filter in the help doesn't work

I am trying to run the code that on the Autodesk help
http://help.autodesk.com/view/RVT/2014/ENU/?guid=GUID-B6FB80F2-7A17-4242-9E95-D6056090E85B
but it seem not to work. The code "FirstElement
().get_Parameter("Comments");"
don't work. No such function.
I got the following error:
Revit encoutered a System.MissingMethodException; Method not found:'AutoDesk.Revit.DB.Parameter Autodesk.Revit.DB.Element.get_Parameter(System.String)
What is the wrong with this code?
private void CreateViewFilter(Autodesk.Revit.DB.Document doc, View view)
{
List<ElementId> categories = new List<ElementId>();
categories.Add(new ElementId(BuiltInCategory.OST_Walls));
ParameterFilterElement parameterFilterElement =
ParameterFilterElement.Create(doc, "Comments = foo", categories);
FilteredElementCollector parameterCollector = new FilteredElementCollector
(doc);
Parameter parameter = parameterCollector.OfClass(typeof(Wall)).FirstElement
().get_Parameter("Comments");
List<FilterRule> filterRules = new List<FilterRule>();
filterRules.Add(ParameterFilterRuleFactory.CreateEqualsRule
(parameter.Id, "foo", true));
parameterFilterElement.SetRules(filterRules);
OverrideGraphicSettings filterSettings = new OverrideGraphicSettings();
// outline walls in red
filterSettings.SetProjectionLineColor(new Color(255, 0, 0));
view.SetFilterOverrides(parameterFilterElement.Id, filterSettings);
}
I guess you are using a version of Revit different from the help version (2014) ?
I think get_Parameter is deprecated since a couple of versions.
You can try with LookupParameter :
...FirstElement().LookupParameter("Comments");
or eventually GetParameters, but careful, this one returns a collections :
...FirstElement().GetParameters("Comments");
(The links refer to the last version but you can easily check for another one on the same site, and the 2 methods looks unchanged since Revit 2015.)

How to update TFS labelname by using VersionControlServer.CreateLabel() [C#][TFS]

I´d like to update a label that was applied to a branch programmatically. While searching for a method that would do the trick, I found the VersionControlServer.CreateLabel()-Method. https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.createlabel(v=vs.120).aspx
I tried it like this, but it doesn´t seem to work:
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(tfsuri));
var vcs = tfs.GetService<VersionControlServer>();
string labelscope = "$/MyProjects/" + machinenumber;
var specifiedBranch = vcs.QueryLabels(label, labelscope, null, true);
string branch = specifiedBranch[0].Items[0].ServerItem;
ItemSpec newItemSpec = new ItemSpec(branch, RecursionType.Full);
string newItem = specifiedBranch[0].Items[0].ServerItem;
newItemSpec.Item = newItem;
VersionSpec versSpec = new LabelVersionSpec(label);
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, false);
LabelItemSpec[] newLabelItemSpecList = new LabelItemSpec[1] { newLabelItemSpec };
string labelOwner = vcs.AuthenticatedUser;
string labelName = label.Insert(6, "ed");
VersionControlLabel labelToUpdate = new VersionControlLabel(vcs, labelName, labelOwner, branch, null);
vcs.CreateLabel(labelToUpdate, newLabelItemSpecList, LabelChildOption.Replace);
What I exactly want to do is to update the old label name from "Deploy" to "Deployed". I know how to do this with TF.exe, but it should work without TF.exe.
Does anyone has an code example how to use the CreateLabel()-Methode for updateting a existing label?
-- UPDATE --
I changed
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, true);
to
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, false);
Now a new Label is created for the same branch. I cann delete the old label with VersionControlServer.DeleteLabel. Then I get the result that I was looking for, But I still would like to know how to update correctly.
Renaming Labels is not supported by TFS. You can only create a new Label based on the old Label you want to remove. Details please see this link: Rename Label in Team Foundation Server
You could also verify this in VersionControlLabel Class.
Name Gets the name of this label.
It's only be able to get the name not set the name.
Update
For the LabelChildOption options in VersionControlServer::CreateLabel Method , there are three options:
Replace: Any item that you specify in your request that’s already in the label will be replaced by what you have specified.
Anything that’s not in the label already will be added to the
label, and existing items that aren’t modified by your request will
remain as they were.
Merge: Leave unmodified items that are in your request but that already exist in the label. Any item in your request that’s not
already in the label will be added to the label, and existing items
in the label that aren’t specified in your label will remain
unchanged.
Fail: Labels have the notion of a scope. The Fail option says that the call to create or update the label should fail if there is
at least one label by the same name that exists at a scope that would
be below the scope of the new label.
The update label only means update the itemSpecs parameter which means the item specs included in the label. So it's used to update the ItemSpec for the label – Which Files, Folder we want to Label.

How can I provide a tab completion list, with the values generated on powershell startup?

So I have a cmdlet written in c#: Get-LivingCharacter. I want users to use this like Get-LivingCharacter -Name "Bran", but I would like to allow for the list of available characters to change. Maybe today, "Bran" is a valid name to pass in for Get-LivingCharacter, but maybe in the future it will not be. Things happen.
For convenience I want to allow tab-completion of this field. However, I can't seem to get that to work for non-const data sets. Dynamic fields don't even auto-complete the field name, nevermind the value, and I don't know a way to implement this for a non-dynamic field. Conceptually, I could generate a .ps1 file on startup given the current data set, and then load that ps1 as the module, but this feels a bit like killing a pup with a greatsword - lots of overkill. Is there a better option?
I had already implemented a similar function to the DynamicParam helper function, as reference in the comments. However, tab completion wasn't working. I was writing a minimal reproduction example, when...my tab completion worked.
It turns out, it reproducibly works/breaks based on the inclusion of a WriteDebug statement:
[Cmdlet("Get", "LivingCharacter")]
public class GetLivingCharacter : Cmdlet, IDynamicParameters
{
protected override void ProcessRecord()
{
}
public object GetDynamicParameters()
{
WriteDebug("Getting names"); // Tab completion won't work with this here - comment it out and it works.
^^^^^^^^^^
var chars = new List<String>() { "Bran", "Arya" };
var dict = new RuntimeDefinedParameterDictionary();
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a valid open name",
Mandatory = true
},
new ValidateSetAttribute(chars.ToArray()),
};
dict.Add("Name", new RuntimeDefinedParameter("Name", typeof(string), attributes));
return dict;
}
}
After some digging, the WriteDebug statement is throwing (which I assume is because it can't output while I'm typing). It then recreates the GetLivingCharacter class after I've finished the command to validate. It took a while to find since, because of the issue, I can't write the error to the console, so I had to append to a temp file instead.

Find a view filter Revit Api

I am trying to use a filter to show/hide a certain element on the view. The family is from catogary GenericModel. I use the same code snippet that on the help on the autodesk site it works fine in its original state (catogary is walls) but when I changed it to GenericModel I got the following error:
"One of the given rules refers to a parameter that does not apply to this filter's categories."
I suspect that something wrong with the typeOf(FamilyInstance).
The original code on Autodesk site is:
http://help.autodesk.com/view/RVT/2014/ENU/?guid=GUID-B6FB80F2-7A17-4242-9E95-D6056090E85B
and here is my code
Transaction trans = new Transaction(doc);
trans.Start("Hide_or_Unhide");
//
List<ElementId> categories = new List<ElementId>();
categories.Add(new ElementId(BuiltInCategory.OST_GenericModel));
ParameterFilterElement parameterFilterElement = ParameterFilterElement.Create(doc, "elementNo = 102", categories);
FilteredElementCollector parameterCollector = new FilteredElementCollector(doc);
Parameter parameter = parameterCollector.OfClass(typeof(FamilyInstance)).FirstElement().get_Parameter("elementNo");
List<FilterRule> filterRules = new List<FilterRule>();
filterRules.Add(ParameterFilterRuleFactory.CreateEqualsRule(parameter.Id, 102));
try
{
parameterFilterElement.SetRules(filterRules);
}
catch (Exception ex)
{
TaskDialog.Show("", ex.Message);
}
OverrideGraphicSettings filterSettings = new OverrideGraphicSettings();
// outline walls in red
filterSettings.SetProjectionLineColor(new Autodesk.Revit.DB.Color(255, 0, 0));
Autodesk.Revit.DB.View curView = doc.ActiveView;
curView.SetFilterOverrides(parameterFilterElement.Id, filterSettings);
trans.Commit();
I think the problem is that your code which is performing the FilteredElementCollector is not specific enough. In the ADN sample, they're filtering on a type of "Wall" - but you're filtering on a type of FamilyInstance. You're correct on the type, but FamilyInstance covers lots of categories. The FirstElement() is giving the first FamilyInstance in the collector (which is likely not a generic model).
Try this line:
Parameter parameter = parameterCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_GenericModel).FirstElement().get_Parameter("elementNo");
That way, you should get the first element that is both a family instance AND a GenericModel.
Good Luck,
Matt

How do you use the CopyIntoItems method of the SharePoint Copy web service?

I am attempting to load document files into a document library in SharePoint using the CopyIntoItems method of the SharePoint Copy web service.
The code below executes and returns 0 (success). Also, the CopyResult[] array returns 1 value with a "Success" result. However, I cannot find the document anywhere in the library.
I have two questions:
Can anyone see anything wrong with my code or suggest changes?
Can anyone suggest how I could debug this on the server side. I don't have a tremendous amount of experience with SharePoint. If I can track what is going on through logging or some other method on the server side it may help me figure out what is going on.
Code Sample:
string[] destinationUrls = { Uri.EscapeDataString("https://someaddress.com/Reports/Temp") };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Name", InternalName = "Name", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Name" };
SPCopyWebService.FieldInformation i2 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1, i2 };
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems("", destinationUrls, info, data, out result);
Edit that got things working:
I got my code working by adding "http://null" to the SourceUrl field. Nat's answer below would probably work for that reason. Here is the line I changed to get it working.
// Change
uint ret = SPCopyNew.CopyIntoItems("http://null", destinationUrls, info, data, out result);
I think the issue may be in trying to set the "Name" property using the webservice. I have had some fail doing that.
Given the "Name" is the name of the document, you may have some success with
string targetDocName = "Test1Name.txt";
string destinationUrl = Uri.EscapeDataString("https://someaddress.com/Reports/Temp/" + targetDocName);
string[] destinationUrls = { destinationUrl };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1};
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems(destinationUrl, destinationUrls, info, data, out result);
Note: I have used the "target" as the "source" property. Don't quite know why, but it does the trick.
I didn't understand very well what you're tying to do, but if you're trying to upload a file from a local directory into a sharepoint library, i would suggest you create a webclient and use uploadata:
Example (VB.NET):
dim webclient as Webclient
webClient.UploadData("http://srvasddress/library/filenameexample.doc", "PUT", filebytes)
Then you just have to check in the file using the lists web service, something like:
listService.CheckInFile("http://srvasddress/library/filenameexample.doc", "description", "1")
Hope it was of some help.
EDIT: Don't forget to set credentials for the web client, etc.
EDIT 2: Update metada fields using this:
listService.UpdateListItems("Name of the Library, batchquery)
You can find info on building batch query's in here: link
The sourceurl is used in Sharepoint. It is a link back to the "Source Document." When in your document library, hover over the item, to the right appears a down pointing triangle. Clicking on it, brings up a menu. Click on the "View Properties" Option. On this page you will see the following "This item is a copy of http://null ( Go To Source Item | Unlink )"
Because we are using the Copy function Sharepoint is keeping track of the "Source item" as part of the Document Management feature.

Categories

Resources