Question

jmatty2000 on Mon, 22 Oct 2012 14:26:33


Hi

I created a class for my form to add the button controls (which tend to get in the way sometimes). I then turned it into a Partial Class of my main form (code below).

Now, when I double click on the button in [design] mode, it loads up the code which is part of the main form rather than taking me stright to the btn Click method.

Can anyone one say why its not taking me straight to the btn Click method? (which I cut and pasted into the Partial Class).

Thanks to anyone who can help

My code in the partial class for the Form is :-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public partial class MainForm : Form
    {
        private void btnDeleteTown_Click(object sender, EventArgs e)
        {
            ExcludedTowns.RemoveAt(listBoxExcludeTowns.SelectedIndex);
            listBoxExcludeTowns.Items.RemoveAt(listBoxExcludeTowns.SelectedIndex);
        }
        private void btnAddTown_Click(object sender, EventArgs e)
        {
            ExcludedTowns.Add(textBoxExcludeTown.Text);
            listBoxExcludeTowns.Items.Add(textBoxExcludeTown.Text);
            textBoxExcludeTown.Text = "";
        }
    }
}

It just seems a bit strange but its also my first time that I've tried to use a partial class - very handy there are too :)

p.s I'm using MS Visual C# 2010 Express edition.



Sponsored



Replies

CoolDadTx on Mon, 22 Oct 2012 15:21:58


So you moved the event handlers out of the core MainForm.cs file and dropped it into a separate file (MainForm.events.cs)?  In that case the designer can't find the event handlers anymore.  Partial classes allow us to move some code outside a file but it really is a parlor trick in that the compiler will put everything back together into a single type during compilation. 

But designers work against files so, in this case, the designer doesn't search all files looking for the implementation as that would be too slow.  The designer only looks at the files associated with the form.  To find these files the designer looks at the main file (MainForm.cs) and any dependent files.  Dependent files are determined by an item setting on each file.  Unfortunately you cannot edit that in VS.  There is a third-party extension that allows you to set up dependencies between files (grouping as it is called).  Grouped items appear under the main item in Solution Explorer.  For example under your form you'll see MainForm.Designer.cs and MainForm.resx.  These are dependent files.  When you added the form the underlying item template set them up as dependencies.  These are the files that the designer might look at.

To get the behavior you want you need to make your new file a dependent on MainForm.cs.  The third-party addin can generate the necessary entries but unfortunately it generates the wrong subtype element.  Since your partial is of a form it marks the file as a form.  The designer (currently) ignores forms that are dependents because that just doesn't happen.  So whether you use the extension (VSCommands) or not you're going to have to edit the project file manually.  If you are using VSCommands then you already have a project context menu option to edit the project file.  Otherwise save your project and then use your favorite text editor to edit it.

Find the entry for MainForm.events.cs (or whatever you called it) and update it to look like this:

<Compile Include="MainForm.events.cs">
   <DependentUpon>MainForm.cs</DependentUpon>
</Compile>

Then reload the project.  MainForm.events.cs will appear under MainForm and the designer will now look at it when looking for event handlers.  Note that the file name convention I used matches the general approach to dependent items.

Michael Taylor - 10/22/2012
http://msmvps.com/blogs/p3net

jmatty2000 on Mon, 22 Oct 2012 20:10:13


Thanks Michael but I created the Partial Class just by clicking Add Class, then renaming it so that it has a similar name as the original form. I didn't do anything complicated like moving the event handlers. I'm still learning the ropes really.

Do you think I added the Partial Class incorrectly - if so how should I be adding one.

Thanks

Matt

CoolDadTx on Tue, 23 Oct 2012 01:20:21


You moved to much of the logic to the partial class.  The main file should remain the core definition.  Your partial file should contain not much more than this:

public partial class MainForm
{
   //Event handlers
}

The designer is getting confused as to which file is the actual main file.  Remove the base class information and everything but the event handlers you care about.  Then fix up the project file as I mentioned and everything should work correctly.

Note that partial classes were added to allow designers to generate code that was separate from user-generated code.  It is not really designed (or correct) to use partial types for your code.  If your source files are getting too big then that is a sign you're design is probably not ideal.  In general your code goes in the main source file and the designer keeps its code in its own file.  If you do want to use partials then VS isn't going to help you much because it isn't a normal approach (outside designer/tool generated code).

Michael Taylor - 10/22/2012
http://msmvps.com/blogs/p3net

jmatty2000 on Tue, 23 Oct 2012 08:14:39


Hi Michael

The problem is that I find that some of the simple button event code tends to get in the way within the main file. Could you recommend any references/books I could use to help me get a good grounding on how to organise my code better.

I learn't about namespaces the other day which really helps but it still looks like I've still not grasped the way I should be managing my projects.

Thanks for your help

Matt

CoolDadTx on Tue, 23 Oct 2012 14:17:10


In general all your event handlers will be in the main form file.  Designer generated code is hidden elsewhere.  If you want testable code then the event handlers will do nothing but call other classes (worker services) to do the actual heavy lifting.  Hence your main form file may be large but it contains nothing but a bunch of 2-3 line event handlers.  If you find that you have hundreds of handlers then it might be time to consider breaking up your form into smaller pieces (user controls or something).

For a WinForms app you should look into Model-View-Presenter pattern.  If you're looking toward WPF then Model-View-ViewModel.  For ASP.NET apps then Model-View-Controller pattern.  These patterns provide a good approach of separating the UI framweork from the real work via worker services.  They will force you to treat the form files as nothing more than boiler plate code that is written once and then forgotten except when interacting directly with the UI framework (responding to events, updating bindings, etc).  You might also consider researching Separation of Concerns but note that these topics assume you already know object-oriented programming really well.  If you don't then you should brush up on that first.

Michael Taylor - 10/23/2012
http://msmvps.com/blogs/p3net

jmatty2000 on Tue, 23 Oct 2012 15:19:56


Hi Michael

I think maybe you've helped me as much as you can now. I've been learning about just creating classes for the Presentation layer, Business Layer and Database Layer. Namespacing is helping enormously me organise better and write the code quicker!!!

Perhaps a was looking to split my code up too much by moving my events to a partial class. At least its good to know that this is a mistake earlier rather than later. I havn't read a book yet that say that its not advisable the move your events to a seperate partial class eg for button click events.

I've got a long way to go but with perseverence I will get there!!

Thanks

Matt