Click here to Skip to main content
15,886,017 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Thank you all so much for helping me so far. I have another question if you wouldn't mind.

The goal I am trying to achive is have one custom control that is a rectangle shape and I would like to add connectors to it as a seperate control so it can overlap the edge of the first rectangle control.

The overall desired effect is like is Visio or Powerpoint where their objects have connectors that overlap the corners of their objects that you can create lines from to connect objects.

So here is what I have done.

1. I have created a custom control that inherits from the control class. I overrode the paint meathod and put some contructors in there and some other stuff. This part of it works fine

2. I created a connector control that is a small 10, 10 square that represents a connector. This all works fine so far.

3. Now this is where I am having trouble. When I create the first control I want it to create 4 of the connector controls and have them just overlapping the center's of the top, left, right, and bottom. I just don't know how to achive this. Any recommendation on this I would gladly hear.

Thank you very much for your help and time,

Thechazm
Posted

My advice is: don't do it this way. This is possible in principle; I knew few attempts, all pretty much unsuccessful; and it's clear why.

I explained what to do in my past solution: Drawing Lines between mdi child forms[^].

The question is not exactly the same as yours, but the right solution would be the same.

Just in case, see also some other past solutions:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
capture the drawing on a panel[^],
How do I clear a panel from old drawing[^],
draw a rectangle in C#[^].

Please pardon some redundancy in my advice — the post were the answers to different questions, they refer to each other, etc.

—SA
 
Share this answer
 
Comments
thechazm 25-Jan-12 17:09pm    
Ok I get your point. I have to ask this one question about your answer. The reason for the program is to manage personnel by re-assigning them to other projects or whatever. So I have a list box on the right that I click and drag to the center of the screen( which is a panel) and it creates the object but also keeping track of the object and sending the data back in SQL to the server. Is this functionality still possible with your solution you offered? If so I am all ears. Thank you for your time.
Sergey Alexandrovich Kryukov 25-Jan-12 17:54pm    
It is absolutely possible and actually easier then with controls. You create one big control for rendering, and develop a system of light-weigh graphical objects placed in data model of the diagram, and the data model is translated in two ways -- to database and to rendering (just call Invalidate). You need to make a sound architecture.

Now, I really recommend you to use these ideas, but using WPF instead of Forms. The WPF approach would be closer to your initial ideas as there is no rendering concerns -- you just put objects on Canvas. Only, unlike connecting controls in Forms, it would look realistic. :-)

I think we all agree that you would be able to switch to WPF, which should pay off soon.
--SA
Espen Harlinn 25-Jan-12 17:24pm    
Good starting point, my 5 :)
Sergey Alexandrovich Kryukov 25-Jan-12 17:49pm    
Thank you, Espen.
--SA
Espen Harlinn 25-Jan-12 17:52pm    
Well - it's time to call it a night Sergey - it's getting late here in Norway :)
I think you are looking for something like this:
WPF Diagram Designer - Part 1[^]
WPF Diagram Designer - Part 2[^]
WPF Diagram Designer - Part 3[^]
WPF Diagram Designer - Part 4[^]

The articles are well written and the concepts fundamental to WPF designer integration, but if you are new to WPF you're in for one heck of a learning experience :)

Moving to WPF will vastly simplify your development, as the platform provides just about everything required to create a Visio like application.

If you want to stick to Windows Forms then Diagram.NET[^] is a free open source diagramming component for Windows Forms.

Another open source (GPL v3) Windows Forms alternative is NShape[^]. NShape is very powerful, but the GPL v3 might be too restrictive - unless you are developing an "inhouse" application that will not be distributed commercially.

Best regards
Espen Harlinn
 
Share this answer
 
v5
Comments
thechazm 25-Jan-12 17:11pm    
I have the program in a Winform but I will look up this WPF side and thank you for your reference. I have watched a few video's on WPF generation but have never done it myself.
Espen Harlinn 25-Jan-12 17:40pm    
Compare the size of the source code for WPF Diagram Designer - Part 4 and the core of Diagram.Net. While WPF may seem a bit "foreign", it packs a lot of "development" power - this is particularly true in those cases where you start to mess around with painting.
Sergey Alexandrovich Kryukov 25-Jan-12 17:46pm    
Espen,

My 5 for this answer.

That would be my next advice -- use WPF. Sorry I forgot to mention this alternative.
The thing is: WPF looks like it was designed with diagramming in mind (I'm sure it was, buy not just for that).

All the concerns of rendering, invalidation, zoom/pan, transforms, graphical components and more, everything which would a whole item in System.Windows.Forms and System.Drawing programming on each of those aspects is already very well implemented in WPF.

So, even if you have zero experience with WPF, learning it will pay off much sooner then anyone implements it all in Forms.

--SA
Espen Harlinn 25-Jan-12 17:47pm    
Thank you Sergey :)
thechazm 25-Jan-12 17:41pm    
Your a life saver and I think I'll accept this solution. I appreciate your help and time on this issue.
Now, lets turn to WPF and let me give you some further ideas before we close this discussion and you continue on your own. I hope you will choose to accept this one formally, too. (You can click green "Accept" button on more than one.)

With WPF, you can put all your diagram elements on the surface of Canvas, please see http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx[^].

The children of the Canvas are of the compile-time of UIElement, and the Canvas.Childen collection is polymorphous. This base class UIElement is quite enough to add all kinds of input events to its real-time instances, to implement all manipulations you need for editing. Please see http://msdn.microsoft.com/en-us/library/system.windows.uielement.aspx[^].

Unlike controls, the WPF elements can freely overlap, be semi-transparent and a lot more. The connectors will also be the children of your Canvas, peer-to-peer with the connected elements. (Not having this arrangement was actually the major problem you expressed in your original post.)

One special advanced advice about it: you can even allow the users to add their custom elements to the diagram. Here is the idea: the user can create their own vector graphics elements of any degree of complexity and save them in XAML format. Your application can easily load them during run-time and add to the canvas. You can dynamically attach any properties to them during run time.

One great way of developing of such vector images the the brilliant Open Source vector editor Inkscape. Please see:
http://en.wikipedia.org/wiki/Inkscape[^],
http://inkscape.org/[^].

You can draw vector graphics in its native SVG format (http://en.wikipedia.org/wiki/Scalable_Vector_Graphics[^]) and export as XAML. You should remember that SVG is richer then XAML, so you could not use some advanced SVG properties such as fuzziness. At the same time, the properties you can export to XAML are quite reach, including gradients, transparency and a lot more. The gallery of available samples is really amazing.

You can solve the problem of zooming and panning of your diagram by putting your whole Canvas in the Viewbox, see http://msdn.microsoft.com/en-us/library/system.windows.controls.viewbox.aspx[^].

Now, you need to create a sound architecture of the system which should define the layers and interaction between them: database, other persistence, exports, loading and edition, all properly synchronized.

First of all, you need to develop a data model of a diagram. Try to segregate the model in two parts: semantic and graphical. At least semantic part of the model should be agnostic to the graphical. Semantic part of the model should model the semantic aspects of the diagram, the application field modeled by the diagram and agnostic to the diagram itself, such aspects as shapes and colors. It should only be concerned with the semantic properties of objects modeled by a diagram and semantic relationships.

This data model should present a separate layer of the architecture. Other layers should communicate only through this model. For example, input events should not deal with database or even with the canvas children properties, but only with the data model. You should poll database and update data model first, and only the graphics can be updated only from the data model. It will provide adequate level of abstraction. For example, later on you will be able to replace your database and mapping code, and it will be relatively easy because only two layers are involved.

You may need to export all the diagram in a local file or sent over the network stream. To do that, use only one thing: Data Contract. This is the most reliable, flexible and non-intrusive way. You have to make your data model a set of pure data classes. To make it a data contract, you only need to add some attributes to types and members. What is very important: you object graph can be an arbitrary graph, not a tree. Data Contract serializers will handle it. You also can organize perfect backup compatibility needed to upgrade the data model. You file type can be made world unique, as you can (and you should) specify your unique (say, company-based) namespace to the meta-data.

See:
http://msdn.microsoft.com/en-us/library/ms733127.aspx[^]

See also my past answers where I advocate this approach:
How can I utilize XML File streamwriter and reader in my form application?[^],
Creating property files...[^],
deseralize a json string array[^].

Now, let's get back to the layered architecture. I suggest you learn and analyze applicability of the following architectural patterns (http://en.wikipedia.org/wiki/Architectural_pattern_(computer_science)[^]):

MVVM — Model View View Model,
http://en.wikipedia.org/wiki/Model_View_ViewModel[^],

MVC — Model-View-Controller,
http://en.wikipedia.org/wiki/Model-view-controller[^]),

MVA — Model-View-Adapter,
http://en.wikipedia.org/wiki/Model–view–adapter[^],

MVP — Model-View-Presenter,
http://en.wikipedia.org/wiki/Model-view-presenter[^].
Pay attention for the motivation of those architectures. If you understand it, you would be able to create robust architecture for this application.

—SA
 
Share this answer
 
v4
Comments
thechazm 25-Jan-12 21:15pm    
Excellent post! Extreamly informative and beneficial. Thank you so much for your time to take building this post.
Sergey Alexandrovich Kryukov 25-Jan-12 21:31pm    
You are very welcome.
Hope that taking this as a base for your route of development will produce great result.

Good luck, call again.
--SA
Espen Harlinn 26-Jan-12 6:27am    
I agree, impressed as usual :)
Sergey Alexandrovich Kryukov 26-Jan-12 11:34am    
Thank you, Espen.
--SA
[no name] 12-Oct-12 7:43am    
Always u r rocking:)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900