Dte.LaunchWizard not showing New Item dialog - visual-studio-extensions

I am trying to add a new item from an item template from a Visual Studio command. I cannot get Visual Studio to show the New Item dialog. This is in Visual Studio 2022.
Regardless of whether I use ItemOperations.AddNewItem or EnvDTE.LaunchWizard(Constants.vsWizardAddItem, ref parameters), the item is added correctly - but silently - with the default name.
This is my code to add the item using LaunchWizard (item is ProjectItem of the currently selected physical folder):
var template = ((Solution2)dte.Solution).GetProjectItemTemplate(templateName, "CSharp");
var prms = new object[]
{
Constants.vsWizardAddItem,
item.Name,
item.ProjectItems,
item.Properties.Item("FullPath").Value?.ToString(),
"Bag",
string.Empty,
false
};
var cached = dte.SuppressUI;
dte.SuppressUI = false;
try
{
dte.LaunchWizard(template, ref prms);
}
finally
{
dte.SuppressUI = cached;
}
The last value of false in the parameter array should mean that the New Item dialog is displayed. But this does not happen, the item is added silently with the default name ("Bag"). I thought maybe the EnvDTE.SuppressUI property could be the reason but setting this to false changes nothing.

We can see from this link:
The first parameter is a GUID that uniquely identifies the launch
context as distinct from Add Item or Add Project or a custom GUID.
Maybe this page can give you some help about ContextParams.
From the documentation we can see that it doesn't apply to VS 2022 SDK. Maybe you can try it in VS 2019.

Related

Visual Studio Extension: Get the path of the current selected file in the Solution Explorer

I'm trying to create my first extension for visual studio and so far I've been following this tutorial to get me started (http://www.diaryofaninja.com/blog/2014/02/18/who-said-building-visual-studio-extensions-was-hard).
Now I have a custom menu item appearing when I click on a file in the solution explorer.
What I need now for my small project is to get the path of the file selected in the solution explorer but I can't understand how can I do that.
Any help?
---------------------------- EDIT ------------------------------
As matze said, the answer is in the link I posted. I just didn't notice it when I wrote it.
In the meanwhile I also found another possible answer in this thread: How to get the details of the selected item in solution explorer using vs package
where I found this code:
foreach (UIHierarchyItem selItem in selectedItems)
{
ProjectItem prjItem = selItem.Object as ProjectItem;
string filePath = prjItem.Properties.Item("FullPath").Value.ToString();
//System.Windows.Forms.MessageBox.Show(selItem.Name + filePath);
return filePath;
}
So, here are two ways to get the path to the selected file(s) :)
For future reference:
//In your async method load the DTE
var dte2 = await ServiceProvider.GetGlobalServiceAsync(typeof(SDTE)) as DTE2;
var selectedItems = dte2.SelectItems;
if(selectedItems.MultiSelect || selectedItems.Count > 1){ //Use either/or
for(short i = 1; i <= selectedItems.Count; i++){
//Get selected item
var selectedItem = selectedItems[i];
//Get associated project item (selectedItem.ProjectItem
//If selectedItem is a project, then selectedItem.ProjectItem will be null,
//and selectedItem.Project will not be null.
var projectItem = selectedItem.ProjectItem;
//Get project for ProjectItem
var project = projectItem.ContainingProject;
// Or get project object if selectedItem is a project
var sproject = selectedItem.Project;
//Is selectedItem a physical folder?
var isFolder = projectItem.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder;
//Else, get item's folder
var itemFolder = new FileInfo(projectItem.Properties.Item("FullPath").ToString()).Directory;
//Find config file
var configFiles itemFolder.GetFiles("web.config");
var configfile = configFiles.length > 0 ? configFiles[0] : null;
//Turn config file into ProjectItem object
var configItem = dte2.solution.FindProjectItem(configFile.FullName);
}
}
I hope someone finds this helpful...
The article you mentioned already contains a solution for that.
Look for the menuCommand_BeforeQueryStatus method in the sample code. It uses the IsSingleProjectItemSelection method to obtain an IVsHierarchy object representing the project as well as the id of the selected item. It seems that you can safely cast the hierarchy to IVsProject and use it´s GetMkDocument function to query the item´s fullpath...
IVsHierarchy hierarchy = null;
uint itemid = VSConstants.VSITEMID_NIL;
if (IsSingleProjectItemSelection(out hierarchy, out itemid))
{
IVsProject project;
if ((project = hierarchy as IVsProject) != null)
{
string itemFullPath = null;
project.GetMkDocument(itemid, out itemFullPath);
}
}
I don´t want to copy the entire code from the article into this answer, but it might be of interest how the IsSingleProjectItemSelection function obtains the selected item; so I just add some notes instead which may guide into the right direction... The method uses the GetCurrentSelection method of the global IVsMonitorSelection service to query to the current selected item.

SSRS Report Viewer - Multi Select Parameter Issue

I am displaying a SSRS reportviewer control in my ASPNET web page. I am using report processing. It works fine for ordinary parameters in the reportviewer but acts strange for multi select parameters. If I click a multiselect parameter, I can see the list flash for a second and then disappear. It does this each time I click it.
Anyone have a solution to stop this flash and disappearance that would allow me to pick from a selection of parameter?
I already tried turning on IE8 compatibility mode, but no luck.
Any suggestions?
Thanks!
// Set the processing mode for the ReportViewer to Remote
reportViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;
Microsoft.Reporting.WebForms.ServerReport serverReport = reportViewer.ServerReport;
// Set the report server URL and report path
string reportURL = string.Empty;
switch (ConfigurationManager.AppSettings["Environment"].ToUpper())
{
case "TEST":
reportURL = ConfigurationManager.AppSettings["testURL"];
break;
case "STAGE":
reportURL = ConfigurationManager.AppSettings["stageURL"];
break;
case "PROD":
reportURL = ConfigurationManager.AppSettings["prodURL"];
break;
default:
this.lblMessage.Text = "Environment not found.";
return;
}
serverReport.ReportServerUrl = new Uri(reportURL);
serverReport.ReportPath = Path.Combine(ConfigManager.ReportingService.BaseReportPath, reportName);
I have this same error in ssrs 2019. If my report contains a lot of parameters, causing a scroll bar to display them all, the only time I get the parameter to fail is when it is at the bottom of the list / bottom of the scrollbar display area. If I simply move that parameter up higher in the list, it then works and the ones moved to the bottom of the list then stop working.

Tridion 2011 Sp1 allow to publish revision version of the component to staging target

Here is a scenario: I have a Page which have Component A. Component A have few linked components B and C. If Editor modifies component B and want to publish to staging target while component still in the workflow so Reviewer can view the changes on staging server before approve component B. When editor preview component he can see the changes, but when he publish to staging target it will grab the last checked in version of the Component A, which still linked to the unmodified version of Component B. How to pragmatically overwrite the default behavior to allow Editor publish his changes to staging environment before completing activity for the item?
Also, when component B inserted directly on the second page I was able to publish from VBScript from workflow automated activity using the following:
Dim strItemURI
strItemURI = CurrentWorkItem.GetItem(2).ID
Dim oComp
Set oComp = TDSE.GetObject(strItemURI, 1)
Call oComp.Publish("tcm:0-13-65537", True, True, False)
Set oComp = Nothing
FinishActivity "Automatic Activity ""Publish to Staging"" Finished"
Do I need to write custom resolver to accomplish above scenario to allow modified version of linked components published to staging environment while in workflow?
Any idea or samples will be appreciated.
Thanks.
Updated:
I'm trying to create TBB, which will replace modified version of the item in the package. Any idea on this? Here is some code:
public void Transform(Engine engine, Package package)
{
try
{
_publicationID = engine.PublishingContext.ResolvedItem.Item.Id.PublicationId;
string stagingTarget = Settings.GetSetting("StagingTargetUri");
PublicationTarget target = new PublicationTarget(new TcmUri(stagingTarget), engine.GetSession());
if(engine.PublishingContext.ResolvedItem.PublicationTarget!=null){
if (stagingTarget.Contains(engine.PublishingContext.ResolvedItem.PublicationTarget.Id.ToString()))
{
foreach (Item item in package.GetAllByType(ContentType.Component))
{
VersionedItem versionedItem = (VersionedItem)engine.GetObject(item);
if (versionedItem.LockType.HasFlag(LockType.InWorkflow))
{
Component componentInWorkflow =
(Component)engine.GetObject(new TcmUri(versionedItem.Id.ItemId, versionedItem.Id.ItemType, versionedItem.Id.PublicationId, 0));
package.Remove(item);
Item mainComponent= package.CreateTridionItem(ContentType.Component,componentInWorkflow);
package.PushItem(mainComponent);
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
According to documentation:
You can publish an item in Workflow if it meets the minimum approval
status set for the Publishing Target. If the item is in Workflow and
does not meet the minimum approval status, the Content Manager
publishes the last checked-in version of the item.
This means that you need to:
Set the Minimum Approval Status on your Publication target as something like "Staging"
As a first step on your Workflow set the Approval Status for your component to "Staging"

How to get Tridion item ID after created using Core Service

I am creating a new item using the Core Service in this post. However, the URI of the newly created item is tcm:0-0-0 instead of the actual TCM URI. the Title property is correct (and not New Component) but the WebDav path returns 'New Component' while .
What is the best way to get the URI of my newly created item?
client.Create(newComponent, null);
string newItemUri = newComponent.Id; // returns tcm:0-0-0
string webDavUrl = newComponent.LocationInfo.WebDavUrl; // returns New%20Component
string title = newComponent.Title; // correct
Second parameter of Create method are ReadOptions. They are used to specify how the item will be read back. In your example you have it set to null, meaning you will not read it back. What you should do is set ReadOptions and assign item read back to a variable, like this:
newComponent = (ComponentData) client.Create(newComponent, new ReadOptions());
Check out Ryan's code at http://blog.building-blocks.com/uploading-images-using-the-core-service-in-sdl-tridion-2011. He uses client.Save to get the saved Component, from which he's able to access the ID.

Flex - Issue with binding in script blocks

I am working on the multifile uploader, and want to set the upload directory based on a selected questionID (which is the directory name) in my datagrid.
The code can be found here http://pastie.org/784185
Something like this:
I have set myQuestionID (the directory to upload to) so it is bindable (lines 136-137):
[Bindable] public var myQuestionID:int;
In my datagrid I use a change handler (line 539):
change="setQuestionID();"
We set the variable in the setQuestionID function (lines 400-407):
[Bindable (event="questionChange")]
private function setQuestionID():void
{
myQuestionID = questionsDG.selectedItem.QuestionID;
dispatchEvent(new Event("questionChange"));
}
And then try to use it in my uploader script (lines 448-475):
// initUploader is called when account info loads
public function getSessionInfoResult(event:ResultEvent):void{
// Get jsessionid & questionid (final directory) for CF uploader
myToken = roAccount.getSessionToken.lastResult;
// BUG: myQuestion is null in actionscript, but okay in form.
var postVariables:URLVariables = new URLVariables();
postVariables.jsessionid = myToken;
postVariables.questionid = myQuestionID;
multiFileUpload = new MultiFileUpload(
filesDG,
browseBTN,
clearButton,
delButton,
upload_btn,
progressbar,
uploadDestination,
postVariables,
350000,
filesToFilter
);
multiFileUpload.addEventListener(Event.COMPLETE,uploadsfinished);
}
I can see in my MXML that the value binded (line 639):
<mx:Label text="{myDirectory}"/>
and it updates when I click a row in my datagrid. However, if I try to access this myQuestionID value inside any action script it will show as null (0). I know my uploader is working as I can hardcode myDirectory to a known directory and it will upload okay.
I'm really stumped.
The reason questionid = null is that getSessionInfoResult() is called by your init code before the bound value of myQuestionID is set.
So your file uploader (multiFileUpload) is already instantiated with myQuestionID = null.
You need to instantiate/pass the value into the multiFileUpload component after it is set.
Use dataGrid change event to set myDirectory everytime the selection has changed by user. this will update the value of myDirectory properly.
By making someID as Bindable would mostly solve your problem if you dont want to use change event on DG

Resources