This message was discovered on microsoft.public.vsnet.ide.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| Uri Dor |
Hi, everyone, After spending a whole day manually fixing this problem I'd like to know if it could have been avoided. The problem is that when a new control is added to a form, the designer gives it a new name such as Label65. Now if two developers edit the same form and add a label they'll both get a Label65 and if they don't rename it, when they try to checkin they'll be in conflict land for a while. What I'd expect the designer to do is to add a developer-specific prefix to such "unnamed" controls, such as tr_Label65 and ud_Label65, so such conflicts won't occur. Is there som easy way to do this in VS.NET 2003 or in Whidbey?
Thx
|
|
| |
| | |
| |
| Peter Huang (VIP) |
Hi Uri,
Now we are researching the issue, and we will update you with new information ASAP.
Best regards,
Peter Huang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights.
|
|
| |
|
| |
| Gary Chang (VIP) |
Hi Uri,
The VS.NET IDE doesn't have such function to customize the default name for a new control adding to a form, however we will pass your concern on this issue to the product team.
Thanks for your understanding!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
| |
| Uri Dor |
Thanks for the reply, Gary, I think this is an important feature for RAD. Is there any chance I can write a macro/add-in that can do this? Is there an event that is fired when a new control is added?
Gary Chang wrote:
[Original message clipped]
|
|
| |
| |
| Gary Chang (VIP) |
Hi Uri,
> Is there any chance I can write a macro/add-in that can do this? Is there an event that is fired when a new control is added? >
yes, I think so, I suggest you refer to the IComponentChangeService.ComponentAdded Event: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/ frlrfSystemComponentModelDesignIComponentChangeServiceClassComponentAddedTop ic.asp
Thanks!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
| |
| Uri Dor |
Thanks, Gary. Could you please give me some starting pointers for someone who's never written an add-in before (I've done macros on VS6, but I understand this can't be done in macros) The add-in itself should be simple, I just don't know anything about all the surrounding interface.
Gary Chang wrote:
[Original message clipped]
|
|
| |
|
| |
| Uri Dor |
Thanks, Gary. Could you please give me some starting pointers for someone who's never written an add-in before (I've done macros on VS6, but I understand this can't be done in macros) The add-in itself should be simple, I just don't know anything about all the surrounding interface.
Gary Chang wrote:
[Original message clipped]
|
|
| |
| |
| Carlos J. Quintero [MVP] (VIP) |
You can find a lot of resources to create add-ins in the Files section of the forum below.
You start creating a basic add-in project (Other projects \ Extensibility Projects \ Visual Studio Add-in). Below is a small VB.NET sample that I have just written to get you started. I will leave to you as exercise to make it robust and to cover things that maybe I have not taken into account.
Imports Microsoft.Office.Core Imports Extensibility Imports System.Runtime.InteropServices Imports EnvDTE Imports System.ComponentModel Imports System.ComponentModel.Design
<GuidAttribute("8FDDEA23-F995-4748-A369-B9B100C287EB"), ProgIdAttribute("MyAddin8.Connect")> _ Public Class Connect
Implements Extensibility.IDTExtensibility2
Private m_objDTE As EnvDTE.DTE Private m_objActiveWindow As Window Private m_objActiveIDesignerHost As IDesignerHost Private WithEvents m_objIComponentChangeService As IComponentChangeService Private WithEvents m_objWindowEvents As EnvDTE.WindowEvents
Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown End Sub
Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdate End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete End Sub
Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnDisconnection End Sub
Public Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode, ByVal addInInst As Object, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnection
m_objDTE = DirectCast(application, EnvDTE.DTE)
m_objWindowEvents = m_objDTE.Events.WindowEvents
End Sub
Private Sub m_objWindowEvents_WindowActivated(ByVal GotFocus As EnvDTE.Window, ByVal LostFocus As EnvDTE.Window) Handles m_objWindowEvents.WindowActivated HandleActiveWindowChange(GotFocus) End Sub
Private Sub m_objWindowEvents_WindowClosing(ByVal Window As EnvDTE.Window) Handles m_objWindowEvents.WindowClosing ' If we are closing the only window that is open, there will not be a WindowActivated event... HandleActiveWindowChange(Nothing) End Sub
Private Sub m_objWindowEvents_WindowCreated(ByVal Window As EnvDTE.Window) Handles m_objWindowEvents.WindowCreated HandleActiveWindowChange(Window) End Sub
Private Sub HandleActiveWindowChange(ByVal objNewActiveWindow As Window)
m_objActiveWindow = objNewActiveWindow m_objActiveIDesignerHost = Nothing
If Not (m_objActiveWindow Is Nothing) Then Try m_objActiveIDesignerHost = DirectCast(m_objActiveWindow.Object, IDesignerHost) m_objIComponentChangeService = DirectCast(m_objActiveIDesignerHost.GetService(GetType(IComponentChangeServi ce)), IComponentChangeService) Catch End Try End If
End Sub
Private Sub m_objIComponentChangeService_ComponentAdded(ByVal sender As Object, ByVal e As System.ComponentModel.Design.ComponentEventArgs) Handles m_objIComponentChangeService.ComponentAdded
Try e.Component.Site.Name = "MyPrefix" & e.Component.Site.Name Catch End Try
End Sub
End Class
--
Carlos J. Quintero (Visual Developer - .NET MVP)
FAQs, Knowledge Base, Files, Docs, Articles, Utilities, etc. for .NET addins: http://groups.yahoo.com/group/vsnetaddin/ (free join)
"Uri Dor" <Click here to reveal e-mail address> escribió en el mensaje news:%Click here to reveal e-mail address... [Original message clipped]
|
|
| |
| |
| Uri Dor |
Thank you so much, Carlos, Only today I have found enough spare time to take your code, paste it in a VB project, translate it into a C# project (so I can add my own stuff - I'm alergic to VB ;-), and run it. It works like a charm - I'll tweak it up a bit and probably put it on SourceForge or something soon.
Thanks have a nice day and enjoy the Olympics :-)
Carlos J. Quintero [MVP] wrote: [Original message clipped]
|
|
| |
| |
| Carlos J. Quintero [MVP] (VIP) |
There are some things that I forgot to mention: the ComponentAdded event is fired not only when you add a fresh control but also:
a) When you paste it from another form b) When you undo/redo operations involving controls.
So, you have to devise some test to see if the control is new or not (such testing if the toolbox is visible, if the Text property is equal to the name property, and so on...)
BTW, there are some pills out there to treat VB.NET allergy ;-)
--
Carlos J. Quintero (Visual Developer - .NET MVP)
FAQs, Knowledge Base, Files, Docs, Articles, Utilities, etc. for .NET addins: http://groups.yahoo.com/group/vsnetaddin/ (free join)
"Uri Dor" <Click here to reveal e-mail address> escribió en el mensaje news:Click here to reveal e-mail address... [Original message clipped]
|
|
| |
| |
| Uri Dor |
The test in this case is simple - whether the name already starts with the prefix. BTW I noticed that ComponentAdded is sometimes fired several times when a single component is added. Anyway, there's a new problem - let's say the user adds a button, which the IDE wants to name "button1". so I rename it to "ud_button1". Now the user adds another button, which the IDE calls "button1" again, since there is no "button1", only "ud_button1". So I try to rename it to "ud_button1" again, which obviously I can't, since the name's taken. The question is how do I find the suffix number I should add, other than looping 1,2,3,4... till I get it right? Is there some way to enumerate or search through all the components on the form? That way I'd check for the last one named "ud_buttonX" and use X+1.
Carlos J. Quintero [MVP] wrote: [Original message clipped]
|
|
| |
| |
| Carlos J. Quintero [MVP] (VIP) |
Use IDesignerHost.Container.Components collection.
--
Carlos J. Quintero (Visual Developer - .NET MVP)
FAQs, Knowledge Base, Files, Docs, Articles, Utilities, etc. for .NET addins: http://groups.yahoo.com/group/vsnetaddin/ (free join)
"Uri Dor" <Click here to reveal e-mail address> escribió en el mensaje news:Click here to reveal e-mail address... [Original message clipped]
|
|
| |
| |
| Uri Dor |
Thanks, both Carlos and Gary, It works like a charm and renames components added to the Form class. But I've found a new problem: I'm using a 3rd party control - specifically Janus ExplorerBar, though the problem will happen with others: The ExplorerBar enables showing groups of items which can be clicked, e.g.:
Customers Add new Delete Produce report
Reports Define new Change existing
or whatever. Now in the form's InitializeComponents, the ExplorerBar adds code that creates each of the groups and items and adds them to the ExplorerBar. Each such item isn't added as a component to the form, but rather is created and assigned to a local variable in InitializeComponents, which is then Add()ed to the ExplorerBar. The names of these local variables is the new place where naming clashes occur and I need to rename. The question is how does the ExplorerBar get a non-taken name for its local variable when it writes the InitializeComponents code (I believe the term is "serializes itself in code")
Thanks Uri
Carlos J. Quintero [MVP] wrote: [Original message clipped]
|
|
| |
| |
| Gary Chang (VIP) |
Hi Uri,
>The question is how does the ExplorerBar get a non-taken name for its local variable when it writes the InitializeComponents code (I believe the term is "serializes itself in code") >
Since the ExplorerBar is a third party component, we are not familiar with it, maybe you can consult their technical support guys...
Thanks for your understanding!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
| |
| Uri Dor |
Thanks Gary, I think this isn't a component-specific problem, otherwise each 3rd party would have to find a way not to collide with other variables in InitializeComponents and I don't see how they do it. How does a component serialize itself in code? Any pointer would be appreciated
Gary Chang wrote: [Original message clipped]
|
|
| |
| |
| Jeffrey Tan[MSFT] (VIP) |
Hi Uri ,
Sorry for letting you wait for so long time.
1. When we create a customized component or control, we can add some customized properties to this component. Normally, a property's serialization is determined through DesignerSerializationVisibilityAttribute, if a property has no DesignerSerializationVisibilityAttribute associated, it will be treated as DesignerSerializationVisibility.Visible. Property with DesignerSerializationVisibility.Hidden will not be serialized in code file. For properties that are collection type, such as Control.Controls property, DesignerSerializationVisibility.Content is need for this property, then the designer knows to serialize the property deeply.
2. When designer decided to serialize a property, it will query if the property's value is the same as its default value. If it is default value, designer will not serialize it. This rule is for performance and code size issue. To specify a property's default value, you can use DefaultValueAttribute or add a private ShouldSerialize<Property Name> method.
3. Now, we are aware of how designer determine whether to serialize a property. If a property's type is customize type, designer will use InstanceDescriptor class to do the customized serialzation. For type that is marked as Serializable, designer will use this object's customize serializer to save it.
4. At last, if we want to add some more customized method or code to the code file, we may use CodeDOM, which gives us a fully control of code serialization.
For a more detailed and official information, please refer to the article below writen by Shawn Burke: "Customizing Code Generation in the .NET Framework Visual Designers" http://msdn.microsoft.com/library/en-us/dndotnet/html/custcodegen.asp?frame= true
=========================================================================== Please apply my suggestion above and let me know if it helps resolve your problem.
Thank you for your patience and cooperation. If you have any questions or concerns, please feel free to post it in the group. I am standing by to be of assistance.
Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
|
|
| |
| |
| Uri Dor |
Thanks, Jeffrey, for the serialization overview - I knew part of it, but not all. The problem here, to be more specific, is: if the serialization code (3rd party or not) uses local variables, how does it know which names to give them? how does it avoid name collisions with other local variables in InitializeComponents? or does it rely on sheer luck?
Jeffrey Tan[MSFT] wrote: [Original message clipped]
|
|
| |
| |
| Jeffrey Tan[MSFT] (VIP) |
Hi Uri,
Thanks very much for your feedback.
First, I did not use that third party components, so I can not tell it what exactly it does. But for a normal component, the instance name serialization should be controlled by Vs.net Designer. Normally, VS.net designer will auto detect the name collision, and rename the component instance name with new one, which is added a bigger numeric number at the end.
If the third party components added some customied code, such as variables in the InitializeComponents, I think it uses CodeDOM(I have referred it in my last reply), and this component did not detect the name collision itself, so the name collision occurs. Anyway, I think you may contact the component company for more help.
Thank you for your patience and cooperation. If you have any questions or concerns, please feel free to post it in the group. I am standing by to be of assistance.
Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
|
|
| |
|
|
|
| |
| Gary Chang (VIP) |
OK, Uri!
I got it, currently I am looking for somebody who could help you on it. We will reply here with more information as soon as possible.
Thanks for your understanding!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
|
|
|
|
|
| |
| Gary Chang (VIP) |
Hi Uri,
It would be like as: ... Dim host As IDesignerHost Dim comp As Component host = CType(EnvDTE.DTE.ActiveWindow.Object, IDesignerHost)
For Each comp In host.Container.Components ... 'comp.ToString() Next
Thanks!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
|
|
|
|
|
| |
| Gary Chang (VIP) |
Hi Uri,
Do you have any problem with MVP Carlos' sample solution, it would work for your need.
By the way, you are welcome to visit our Visual Studio Extensibility portal website: http://msdn.microsoft.com/vstudio/extend/ There you will find information on the various ways to customize, extend, and integrate with the Visual Studio environment, including macros, add-ins and the Visual Studio Industry Partner (VSIP) Program SDK.
Also you the following FAQ is for your reference: Frequently Asked Questions About Visual Studio .NET Automation http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechar t/html/vstchfaqaboutvsnetautomation.asp
Thanks!
Best regards,
Gary Chang Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights. --------------------
|
|
| |
|
|
|
|
|
|
|
|
|