How to get IWpfTextView from command Visual Studio Extension 2017 - c#

I need to show popup use TextViewAdornment, it's require IWpfTextView.
There is old code to that:
private IWpfTextView GetWpfTextView(IVsTextView vTextView)
{
IWpfTextView view = null;
IVsUserData userData = vTextView as IVsUserData;
if (null != userData)
{
IWpfTextViewHost viewHost;
object holder;
Guid guidViewHost = DefGuidList.guidIWpfTextViewHost;
userData.GetData(ref guidViewHost, out holder);
viewHost = (IWpfTextViewHost)holder;
view = viewHost.TextView;
}
return view;
}
but when go to Visual studio 2017 Extension DefGuidList.guidIWpfTextViewHost is missing. So I cannot get IWpfTextView anymore.
Please help me.
Thank you everyone.

After Sergey Vlasov answer I found a solution:
private IWpfTextView GetWpfView()
{
var textManager = (IVsTextManager)ServiceProvider.GetService(typeof(SVsTextManager));
var componentModel = (IComponentModel)this.ServiceProvider.GetService(typeof(SComponentModel));
var editor = componentModel.GetService<IVsEditorAdaptersFactoryService>();
textManager.GetActiveView(1, null, out IVsTextView textViewCurrent);
return editor.GetWpfTextView(textViewCurrent);
}
You must add some reference manual by Add Reference -> Assemblies -> Extensions. Then choose:
Microsoft.VisualStudio.ComponentModelHost
Microsoft.VisualStudio.Editor

Related

Can't see values of properties created in C#

Good Morning,
Introduction:
My problem is about C# dll and VB6. And it refers to the reason of why I can't see the values of the C# properties, but I can see the same values of those properties in my VB6 project.
Explanation:
I created a dll file and a tlb file from a Windows Form Application with VS19 (Visual Studio 2019).
I moved into Properties -> Application and I changed the "Output type" from "Windows application" to "Class Library". After, I clicked in "Assembly information" and I checked the COM visible voice at the bottom of the window that appeared when I clicked.
After that I moved in "Compilation" and checked the "Interop COM" checkbox at the bottom.
In the end I compile the solution and moved the two files in a Virtual Machine (Win XP 32bit SP3), created with Virtual Box. where there's my application developed in VB6.
In my VB6 project I can set and use properties and method of the .NET dll and I see the values (EOL and EOLs are my .NET classes).
Like this:
Vin_car_11 = Mid$(frmInput.txtVinCode.Text, 11, 1)
Select Case Vin_car_11
Case "2"
EOL.XMLPrdWsUrl = "URL" 'Brescia
Case "5"
EOL.XMLPrdWsUrl = "URL" 'Suzzara
Case "9"
EOL.XMLPrdWsUrl = "URL" 'Bolzano
End Select
EOL.Vin = frmInput.txtVinCode.Text
EOL.Van = frmInput.txtVanCode.Text
returnCode = EOLs.GetXMLFile()
Here the problem:
Why I see the value of "EOL.vin" in VB6, but I can't see the same value in C#?
Here the code of my EOL class:
public class cEOL
{
private string vin;
public string Vin
{
get
{
return this.vin;
}
set
{
this.vin = value;
}
}
}
Here the code of my EOLs class:
public class cEOLs
{
#region DICHIARAZIONI
Vehicle.AuthHeader auth;
cEOL EOL;
string result;
string errorDescr;
#endregion
#region COSTRUTTORE
public cEOLs()
{
EOL = new cEOL();
auth = new Vehicle.AuthHeader();
result = "";
errorDescr = "";
}
#endregion
#region METODO
public int GetXMLFile()
{
//chiave di autenticazione server rilasciato da EHSA (IVECO)
auth.AuthKey = "Key";
var client = new Vehicle.EOLClientsAPI4EXT { Url = EOL.XMLPrdWsUrl };
EOL.ReturnCode = client.GetProductionXML(EOL.Vin, EOL.Van, out result, out errorDescr);
EOL.Result = result;
EOL.ErrorDescr = errorDescr;
return EOL.ReturnCode;
}
#endregion
THANKS IN ADVANCE! I HOPE I WAS CLEAR IN THE EXPLANATION!
I resolved it by myself by simply creating a method that returns a string.
I recall this method in my VB6 project for setting the value of the property.
Here the method:
public string ImpostaVIN(string vin)
{
EOL.Vin = vin;
return EOL.Vin;
}
Here the call in VB6:
EOL.Vin = EOLs.ImpostaVIN(string)

How to find current UIViewController in Xamarin

I am using the Facebook Auth SDK, with a Xamarin Forms C# example. However, the Facebook SDK has depreciated the method and replaced it with one which adds a fromViewController variable into the constructors. I am not particularly comfortable with the concept of ViewControllers in Xamarin, or indeed with this code as it is from a sample, so is there a way to gauge the current ViewController?
I have seen a few .net examples e.g. NSArray *viewContrlls=[[self navigationController] viewControllers];[viewContrlls lastObject]; However, this approach doesn't seem to work with Xamarin, as self doesn't contain definitions for navigationControllers.
Alternatively, is there any way of easily working out which variable my current ViewController is sotored in, using the sample code?
Update
This method has become a bit more complex in order to support newer iOS versions in race conditions. This is the new version of the utility with some improvements:
public static UIViewController? GetTopViewController()
{
var window = UIApplication.SharedApplication.GetKeyWindow();
var vc = window?.RootViewController;
while (vc is { PresentedViewController: { } })
vc = vc.PresentedViewController;
if (vc is UINavigationController { ViewControllers: { } } navController)
vc = navController.ViewControllers.Last();
return vc;
}
public static UIWindow? GetKeyWindow(this UIApplication application)
{
if (!UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
return application.KeyWindow; // deprecated in iOS 13
var window = application
.ConnectedScenes
.ToArray()
.OfType<UIWindowScene>()
.SelectMany(scene => scene.Windows)
.FirstOrDefault(window => window.IsKeyWindow);
return window;
}
Old answer
The accepted answer won´t give you the current view controller if it´s in the stack of a parent UINavigationController, so I came up with the following:
public static UIViewController GetTopViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
vc = vc.PresentedViewController;
if (vc is UINavigationController navController)
vc = navController.ViewControllers.Last();
return vc;
}
The best way to do this is to pass in a reference to the ViewController that is calling the Auth method.
However, you can also try this approach (courtesy of AdamKemp on the Xamarin Forums)
var window= UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}

Output Build Order of Visual Studio solution to a text file

Is there a way to output the Build order to a text file via command line?
To explain: We use multiple branches of source and have large solutions of 100+ projects on each branch. I need to write build scripts to build these solutions from command line. We can then tailor the solutions on the branches to only have project references for the projects that team are working on. This should greatly increase solution load time and ease the frustration of the Developers and me, I hope :)
I'm going to keep looking and maybe look at using C# and the APIs provided with VS. We are using 2012 update 1.
This is a good candidate for a Visual Studio Plugin project.
Create a new Visual Studio Add-in project.
In the project creation wizard make sure you choose the following configuration in the Choose Add-in Options step (the other steps are not important, I'm assuming you'll use C#):
In the Connect.cs file, add the following fields:
private BuildEvents _buildEvents;
private Events _events;
private bool buildEventConnected = false;
And add / modify these methods accordingly:
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
_events = _applicationObject.Events;
_buildEvents = _events.BuildEvents;
if (connectMode != ext_ConnectMode.ext_cm_UISetup && !buildEventConnected)
{
_buildEvents.OnBuildDone +=
new _dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
buildEventConnected = true;
}
}
private void BuildEvents_OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
{
const string BUILD_OUTPUT_PANE_GUID = "{1BD8A850-02D1-11D1-BEE7-00A0C913D1F8}";
TextDocument txtOutput = default(TextDocument);
TextSelection txtSelection = default(TextSelection);
Window vsWindow = default(Window);
vsWindow = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
OutputWindow vsOutputWindow = default(OutputWindow);
OutputWindowPane objBuildOutputWindowPane = default(OutputWindowPane);
vsOutputWindow = (OutputWindow)vsWindow.Object;
foreach (OutputWindowPane objOutputWindowPane in vsOutputWindow.OutputWindowPanes)
{
if (objOutputWindowPane.Guid.ToUpper() == BUILD_OUTPUT_PANE_GUID)
{
objBuildOutputWindowPane = objOutputWindowPane;
break;
}
}
txtOutput = objBuildOutputWindowPane.TextDocument;
txtSelection = txtOutput.Selection;
txtSelection.StartOfDocument(false);
txtSelection.EndOfDocument(true);
objBuildOutputWindowPane.OutputString(System.DateTime.Now.ToString());
txtSelection = txtOutput.Selection;
var solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName);
System.IO.File.WriteAllText(solutionDir + "\\build_output.log", txtSelection.Text);
}
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
{
if (buildEventConnected)
{
_buildEvents.OnBuildDone -= new _dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
buildEventConnected = false;
}
}
That's it, on every build you'll have the output sent to the build_output.log file in your solution's folder.
Quick way is to do a "Clean Solution" so that you can see the inverted order in build log.

Custom workflow activity errors 'Value cannot be null'

I'm creating a custom workflow activity in VS2010 targeting .NET 3.5. The DLL is actually being used in a Microsoft System Center Service Manager custom workflow, but I don't think that is my issue.
I have a public string property, that the user types in the string of what the activity should use. However, when the WF runs, it errors out 'value cannot be null'. I want to target if it is my code or something else.
When we drag my custom activity onto the designer, I'm able to type in the text of the string on the designer for that property.
public static DependencyProperty ChangeRequestStageProperty = DependencyProperty.Register("ChangeRequestStage", typeof(String), typeof(UpdateChangeRequestStage));
[DescriptionAttribute("The value to set the ChangeRequestStage Property in the ChangeRequest Extension class.")]
[CategoryAttribute("Change Request Extension")]
[BrowsableAttribute(true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public String Stage
{
get { return ((String)(base.GetValue(UpdateChangeRequestStage.ChangeRequestStageProperty))); }
set { base.SetValue(UpdateChangeRequestStage.ChangeRequestStageProperty, value); }
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
EnterpriseManagementGroup emg = CreateEMG();
//System.WorkItem.ChangeRequest Extension - ClassExtension_928bec0a_cac4_4a0a_bd89_7146c9052fbe
ManagementPackClass mpcChangeRequest = emg.EntityTypes.GetClass(new Guid("8c6c6057-56ad-3862-47ec-dc0dde80a071"));
//System.WorkItemContainsActivity Relationship Class
ManagementPackRelationship workItemContainsActivityRelationship = emg.EntityTypes.GetRelationshipClass(new Guid("2DA498BE-0485-B2B2-D520-6EBD1698E61B"));
EnterpriseManagementObject changeRequest = null;
//Loop thru each emo (Change Request in this case), and assign it. There will never be more than 1 emo returned
foreach (EnterpriseManagementObject obj in emg.EntityObjects.GetRelatedObjects<EnterpriseManagementObject>(executionContext.ContextGuid, workItemContainsActivityRelationship, TraversalDepth.OneLevel, ObjectQueryOptions.Default))
{ changeRequest = obj; }
EnterpriseManagementObjectProjection emop = new EnterpriseManagementObjectProjection(changeRequest);
if (emop != null)
{ emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage; }
emop.Commit();
return base.Execute(executionContext);
}
Since it is getting a 'value cannot be null' error, I'm guessing it's on this line:
emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage;
I'm going to test and see if hardcoding a value works or not. Any ideas?
enter code here
try this
if (emop != null && emop.Object[mpcChangeRequest, "ChangeRequestStage"] != null)
emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage
I didn't want to leave this question wide open, so I'm updating it as to how I resolved this (a long time ago).
Rather than working with an EnterpriseManagementObjectProjection (emop), I worked with a standard EnterpriseManagementObject (emo). From there, I was able to follow a similar format from above:
ManagementPackClass mpcChangeRequest = emg.EntityTypes.GetClass(new Guid("8c246fc5-4e5e-0605-dc23-91f7a362615b"));
changeRequest[mpcChangeRequest, "ChangeRequestStage"].Value = this.Stage;
changeRequest.Commit();

Custom control generate code at design time

Is it possible to write a control which can create/ modify a code file in the same project - (Along the lines of the how the form designer works). I can't see the actual creating / modification of files being troublesome - however I would like to avoid the 'xyz file has been modified - would you like to reload it?' dialogue.
To be honest I'm not expecting that I can without writing a plug in or something of the like.
Absolutley, take a look at the CodeDom: -
http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx
Alternatively look into creating a Visual Studio Add-in: -
http://www.c-sharpcorner.com/UploadFile/mgold/AddIns11292005015631AM/AddIns.aspx
Cheers,
Phil.
This is indeed possible to do. After referencing EnvDTE
using EnvDTE;
var host = this.Container as IDesignerHost;
var dte = host.GetService(typeof(DTE)) as DTE;
var activeDoc = dte.ActiveDocument;
var project = activeDoc.ProjectItem.Collection.Parent as Project;
project.ProjectItems.AddFromFile("\\Test.cs");
As Plip stated, use CodeDom and more specifically - CodeDocSerialier.
Here`s a short example:
[Serializer(typeof(MySerializer))]
class MyControl : Control {}
class MySerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager, object value)
{
CodeDomSerializer baseSerializer;
CodeStatementCollection statements;
CodeExpression targetObject;
if(manager == null || value == null)
{
return null;
}
baseSerializer = (CodeDomSerializer)manager.GetSerializer(typeof(MyControl).BaseType, typeof(CodeDomSerializer));
statements = baseSerializer.Serialize(manager, value) as CodeStatementCollection;
if(statements == null)
{
statements = new CodeStatementCollection();
}
targetObject = GetExpression(manager, value);
if(targetObject != null)
{
// add 'myControl.Visible = true;' statement.
statements.Add(
new CodeAssignStatement(
new CodeFieldReferenceExpression(targetObject, "Visible"),
new CodePrimitiveExpression(true)));
}
return statements;
}
}

Categories

Resources