.NET Forum / Windows Forms / Design Time / October 2007
Trap a build start event from designer
|
|
Thread rating:  |
bmelt - 20 Sep 2007 23:28 GMT I'm developing a custom .Net control (in C++), in which I can set values in Designer. I need to validate those values before build started, so I would like to trap event when I click on "Build" or "Start debugging" (press F7 or F5). Could you please provide any advice how to do it.
Linda Liu [MSFT] - 21 Sep 2007 09:01 GMT Hi Boris,
Based on my understanding, you'd like to validate the value of some custom properties of your custom control before build starts. If I'm off base, please feel free to let me know.
In fact, you needn't trap the build start event from designer to get what you want. Instead, you could put the validating code in the set accessor of the custom property.
The following is a sample:
public ref class MyControl: public System::Windows::Forms::UserControl { private: System::String^ s; public : property System::String^ S { System::String ^ get() { return s; } void set(System::String ^ value) { if(value=="123") { throw gcnew Exception("invalid data"); } s = value; } } }
Build the project and add the custom control on your form. If you set the value of the property S in the Properties window to "123", a dialog pops up saying "Property value is not valid" and forces you to change the value.
Hope this helps. If you have any question, please feel free to let me know.
Sincerely, Linda Liu Microsoft Online Community Support
================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
bmelt - 21 Sep 2007 16:20 GMT Hi Linda, I apologize I simplified the problem so it became unclear. Unfortunately the problem is more complex and I still need to trap a build start event. My custom control is a grid, it is possible to type value into a grid cell at design time and this value is saved by custom Serializer when I click on another cell (or use tab). If I type a value in a cell and begin build/run the WinForm with my grid on it, the value get lost. To validate and save this value I need to click another cell before build/run, but it would be rather better to trap a build start event to save value typed into the last cell.
Regards, Boris
> Hi Boris, > [quoted text clipped - 59 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Linda Liu [MSFT] - 23 Sep 2007 18:01 GMT Hi Boris,
Thank you for your prompt reply!
Generally speaking, if we make some changes in design time and then build the project directly, VS IDE saves the changes first which serializes the changes to code and then begin the compilation.
Could you provide more information about your custom control and custom serializer? If it is difficult to describe, you may send me a simple project that could just reproduce the problem.
To get my actual email address, remove 'online' from my displayed email address.
Sincerely, Linda Liu Microsoft Online Community Support
bmelt - 26 Sep 2007 22:12 GMT Hi Linda, In my app, custom control is a grid. If I set value in grid cell using properties, yes, IDE saves changes before compilation. It looks more convenient for users to type values in grid cells directly, and update properties when cell value is stored (serializer is called in my code). The problem is that cell's new value is not stored with each character typed, but only when moving to another cell. If user types new value and forget to move to another cell before pressing F5, new value is not stored before compilation. From this point, it would be convenient to trap build start event and store the last cell value before compilation. If you'll not be able to help me trap this event, I'll try to find a workaround in control itself changing value store code. I see that using MenuCommandService class we can handle some menu commands in Designer. Is it possible to solve my problem with this or with something similar? Commands that I need are not in StandardCommands so it seems I just need a GUID and command ID for "Build" menu item to use MenuCommandService ? If this should work, where can I find GUID and command ID for menu items I'm interested in?
Regards, Boris
> Hi Boris, > [quoted text clipped - 14 lines] > Linda Liu > Microsoft Online Community Support Jack Jackson - 26 Sep 2007 23:03 GMT If you are using a DataGridView, you can force changes to be committed immediately instead of when leaving the field. Maybe that would help.
Protected Overrides Sub onCurrentCellDirtyStateChanged(ByVal e As System.EventArgs) MyBase.OnCurrentCellDirtyStateChanged(e)
If IsCurrentCellDirty Then CommitEdit(DataGridViewDataErrorContexts.Commit) End If End Sub
>Hi Linda, > [quoted text clipped - 38 lines] >> Linda Liu >> Microsoft Online Community Support bmelt - 26 Sep 2007 23:52 GMT Hi Jack, Thanks for your suggestion. Grid used is not the DataGridView, but I believe the problem should be similar. There are 3 possible events when changes in the last modified cell could be commited: --on typing each character, --on end editing (like pressing enter or leaving the cell), --on start compilation To avoid lost of the latest change in case user miss the 2nd type of event, we can use 1st or 3rd ones. I would prefer the 3rd one - it looks more efficient. If it is impossible, I'll work on the 1st one, similar to your suggestion - as I actually mentioned in my previous update. I hope there is a way to trap build start event from Designer using MenuCommandService class or something similar, it just not clearly documented.
Regards, Boris
> If you are using a DataGridView, you can force changes to be committed > immediately instead of when leaving the field. Maybe that would help. [quoted text clipped - 50 lines] > >> Linda Liu > >> Microsoft Online Community Support Linda Liu [MSFT] - 27 Sep 2007 09:24 GMT Hi Boris,
Thank you for your reply!
The MenuCommandService class implements the IMenuCommandService interface, which is the managed interface used to add handlers for menu commands and to define verbs. However, the Build/Start Debugging commands are not commands on a designer, instead, they're commands of Visual Studio IDE.
So it's impossible to trap a build start event from designer.
> The problem is that cell's new value is not stored with each character typed, but only when moving to another cell.
When we make any change on a control in the designer, the changes should be serialized into the InitializeComponent method immediately, even if we don't save the changes.
I suggest you to type new value in a grid cell and switch to the code view to see if the changes are serialized into the form's InitializeComponent method.
If you could create a simple project that could reproduce the problem, I still recommend you to send the sample project to me. Then I may give you a direct assistance.
I look forward to your reply.
Sincerely, Linda Liu Microsoft Online Community Support
bmelt - 01 Oct 2007 18:08 GMT Hi Linda, Yes, probably it makes sense for me to invoke serialization after typing each character into a cell.
BTW, I'm still wondering if we can trap Visual Studio events in Designer - it may be possible through EnvDTE? Can we use from custom control at design time something like EnvDTE80::DTE2 ^dte2 = (EnvDTE80::DTE2^)Marshal::GetActiveObject("VisualStudio.DTE.8.0"); dte2->Events->BuildEvents->OnBuildBegin += gcnew _dispBuildEvents_OnBuildBeginEventHandler (this,&MyControl::BuildEvents_OnBuildBegin); void BuildEvents_OnBuildBegin(vsBuildScope Scope, vsBuildAction Action) { } I could not figure out how to get it working yet.
Regards, Boris
> Hi Boris, > [quoted text clipped - 28 lines] > Linda Liu > Microsoft Online Community Support Linda Liu [MSFT] - 04 Oct 2007 10:56 GMT Hi Boris,
Thank you for your feedback!
I am performing research on this issue and will get the result back to you ASAP.
I appreciate your patience!
Sincerely, Linda Liu Microsoft Online Community Support
Linda Liu [MSFT] - 08 Oct 2007 11:11 GMT Hi Boris,
I did some research on the EnvDTE.
I tried to get the current VS IDE instance and subscribe the OnBuildBegin event in a derived control designer. But when I add the custom control onto a form, I get an exception, which is about COM interop.
In my opinion, EnvDTE is usually used in developing VS IDE add-ins and is not intended to be used in a custom designer.
If your original problem is still not solved, I'm still willing to have a look at the code of your custom designer.
Sincerely, Linda Liu Microsoft Online Community Support
Linda Liu[MSFT] - 12 Oct 2007 09:31 GMT Hi Boris,
After doing more research on EnvDTE, I manage to get the current running VS IDE instance in a custom designer and get notified when the build starts. Please ignore my previous reply about EnvDTE.
The following are the steps of my test.
1. Create a Visual C++ CLR Windows Forms Control Library project. 2. Add references to EnvDTE, EnvDTE80 and System.Design assemblies in this project. 3. Add the following code in the custom UserControl.h file:
using namespace EnvDTE; using namespace EnvDTE80; namespace CControl {
public ref class MyDesigner: System::Windows::Forms::Design::ControlDesigner { public: virtual void Initialize(System::ComponentModel::IComponent^ component) override { ControlDesigner::Initialize(component); DTE2^ dte2; dte2 = (DTE2^)System::Runtime::InteropServices::Marshal::GetActiveObject("VisualStu dio.DTE.8.0"); dte2->Events->BuildEvents->OnBuildBegin += gcnew _dispBuildEvents_OnBuildBeginEventHandler(this,&MyDesigner::BuildEvents_OnBu ildBegin);
}
void BuildEvents_OnBuildBegin(vsBuildScope Scope, vsBuildAction Action) { System::Windows::Forms::MessageBox::Show("Build Starts..."); } };
[Designer(CControl::MyDesigner::typeid)] public ref class CControlControl : System::Windows::Forms::UserControl { .... }; }
4. Build the project. 5. Add a new Visual C++ CLR Windows Forms Application project in the same solution and drag the custom UserControl from the Toolbox onto the form in the WinForm application project. 6. Build the solution. A messge box saying "Build Starts..." pops up.
Please try it on your side to see if it works and let me know the result.
Sincerely, Linda Liu Microsoft Online Community Support
bmelt - 15 Oct 2007 16:16 GMT Hi Linda, Thank you for confirmation DTE works for this purpose. I managed to get my control working either with GetActiveObject or DTE ^dte = (DTE^)GetService(DTE::typeid); (this looks like a more stright way).
Best regards,
Boris
> Hi Boris, > [quoted text clipped - 56 lines] > Linda Liu > Microsoft Online Community Support
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|