C# operator I didn’t know: ??

Tags:
No Comments »

I didn’t know how this could happen. There’s a operator part of the language I love and I didn’t see it anywhere till today. I think many of you didn’t knew about the ?? operator either. And by the way: it is part of C# since C# 2.0!

How often do you write code like this?

string a, b;
if (a == null)
    b = "some default value";
else
    b = a;

You have to check for null and use some default value if your object is null. The code can be written a little bit shorter with the ?: operator:

b = (a == null) ? "some default value" : a;

It’s nice but with the ?? operator it is much cooler:

b = a ?? "some default value";

Let me quote the msdn library: "The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand."

You can use this operator with every object type and with every nullable type (like int?).

iTunes and multiple libraries

Tags:
1 Comment »

For some reason it can be a good idea to manage your music shared over multiple libraries in iTunes. For example I have one library with all music stored on the disk of my notebook – this is my favorite music and I use this library when I travel. At home much more music is stored on a Linux server and I can access this music over a samba share. My second library holds all the music I can only listen to at home.

But it seems there is no function in iTunes called open library or similar. It is a well hidden feature: when starting iTunes just hold the Shift-key until the following dialog appears.

iTunesChooseLibrary

 

(On a Mac another key is used to get to this dialog. It’s one of shift, command, apple-key but since I don’t own a Mac I don’t know. Maybe someone can comment it.)

Visual Studio – more recent projects

Tags:
No Comments »

The start page of VS offers a list of the recent projects. It’s default length is 6, which is usually too short. I just found out that you can increase this length up to 24 in the Options\Enviroment\General-Tab.

. bla[7]

I am happy.

Subversion deadlock and Copernic desktop search

Tags:
No Comments »

Subversion is just the right thing for the small sized projects Benjamin and I do. We like it, put it’s not perfect and sometimes you find yourself in a deadlock like this one: Committing fails, because you need to update. Updating fails, because you database is corrupt and needs a clean-up. Cleaning-up fails, because there is lock on some files or folders from a previously failed action. Releasing the lock fails for any other reason.

After working with subversion (and the Tortoise-client) for a couple of years I know how to handle most problems, but last week I ran into an really persistent deadlock that drove me crazy. After almost two hours and finally attacking the problem with process-explorer, I found the cause: Copernic desktop search had locked a file inside a .svn – Folder, so it couldn’t be changed or deleted.

So be sure to have the "Indexing performance" of Copernic desktop search or similar tool switched off, when working with Subversion.

bla[7]

Finding and removing a default command in DSL Tools (part 4 of Compartment Mappings)

Tags: , , , , ,
2 Comments »

[Update (2008-05-21): This code is now hosted at CodePlex as part of JaDAL. And a follow-up article was published.]

Previously on…

This article is part of a series. A table of contents can be found at the end of the first article. Part 2 contains a user guide and in part 3 I showed most of the internals of the library.

The "Reroute" command

For each connector there is a command named "Reroute" in the context menu of the DSL editor. Now I have to remove this command for the compartment entry mappings. If the user would use it, the layout of my connectors will be destroyed. Unfortunately I did not find an option, an extension point or anything else where I could change or handle this particular command or the context menu of the connectors.

The generated code

First I looked at the generated code of my Dsl and DslPackage project. There is a GeneratedVSCT.vsct file. In vsct files the commands are defined, but in this one I could not find anything with "Reroute". Then I searched for the string "Reroute" in all files and found nothing.

The DSL binaries

I found no documentation for this command and  was a little desperate. I needed to find the place where it comes from. I searched the whole VS SDK folder (text and binary files) for the string "reroute". A promising hint was found in the Microsoft.VisualStudio.Modeling.Sdk.Shell.dll file. Now let’s go to the Reflector and take a deeper look inside.

After a while I found the Microsoft.VisualStudio.Modeling.Shell.CommandSet class. And hey, in the msdn documentation article for this class there is also the Reroute Line command mentioned. With this knowledge one can easily find the generated CommandSet.cs file as part of the DslPackage. In this file there are two classes AbcCommandSetBase and AbcCommandSet where Abc is the name of you DSL project.

The design pattern of this classes is called double derived and can be found quiet often within the generated DSL code. The ...Base class stays abstract and derives from a class defined in the Microsoft Visual Studio SDK libraries, in this case from the CommandSet class I found above. All code created by the code generator is added to this ...Base class. The other class derives from the ...Base class and is empty – all parts of the project uses this one. Since it is declared with the partial keyword, the user can override ALL methods and change the behavior of all aspects of this class.

And that is what we are going to do: override the GetMenuCommands() method and remove the reroute command:

protected override IList<MenuCommand> GetMenuCommands()
{
  // get the base list
  IList<MenuCommand> cmds = base.GetMenuCommands();
  // find the reroute command  
  MenuCommand rerouteCommand = cmds.First(
    c => c.CommandID == CommonModelingCommands.RerouteLine);
  // if found, remove it
  if (rerouteCommand != null)
      cmds.Remove(rerouteCommand); 
  
  // and return the changed list
  return cmds;
}

That’s it. Pretty easy, but you have to discover where to add this logic.

Connectors between compartment shape entries with DSL Tools – part 3

Tags: , , , , ,
3 Comments »

[Update (2008-05-21): This code is now hosted at CodePlex as part of JaDAL. And a follow-up article was published.]

Previously on…

This article is part of a series. The table of contents can be found at the end of the first article. In that article you can also find a brief overview. In the second part there is a short user guide and a download link of the source code and binaries.

How does it all work?

I don’t want to explain every single detail of my code. If you want to go that deep, you have to read the source code yourself and maybe you will find some comments. I will only show you the fundamental parts of the CompartmentMapping library.

There are a few things you have to consider to achieve the aim of the library:

  1. When creating a connector from Shape A to Shape B how should I get and store the Compartment Entry information for the Reference Relationship?
  2. After that, the connector representing this relationship must be drawn in such a way that it seems to be a connector from one entry to another.
  3. What can a user do to destroy the layout of my connectors? And even more important: how can I prevent him from doing so?
  4. If the user deletes a compartment entry that is part of a relationship, the relationship needs to be deleted, too.

The Connection Builder

There is the concept of Connection Builders used by the DSL Tools. While your day to day use of DSL, you don’t have to worry about Connection Builders since they will be generated by the DSL Tools code generator. But you can turn this generation off and provide your implementation of a Connection Builder for a certain relationship. (see number 5 in the user guide).

A Connection Builder is a static class and will be assigned to a connection toolbar item of your editor. This class contains four interesting methods:

  1. bool CanAcceptSource(ModelElement)
  2. bool CanAcceptTarget(ModelElement)
  3. bool CanAcceptSourceAndTarget(ModelElement, ModelElement)
  4. ElementLink Connect(ModelElement, ModelElement)

The first two methods are used to determine if a particular ModelElement can act as source or target of you connection. For example you can check the ModelElement for a certain property to be set and only allow elements with this property as source and with another property as target, or whatever.

With  CanAcceptSourceAndTarget() you can check whenever a concrete combination of source and target ModelElements is allowed to be connected by your relationship.

Last but not least with the Connect() method you have to create this new relationship for the two selected ModelElements.

In such a Connection Builder I will add the logic to check not only the model elements but also the selected entry inside the Compartment Shape. At this point I will mix the model representation (containing of Domain Classes and Relationships) and the graphical appearance (containing of Shapes and Connectors) but there is no better way at this time since the DSL Tools can only create connectors from shape to shape.

The first problem I ran into: How to get the shape of the model element in the Connection Builder if the only parameter is the ModelElement? I used the PresentationViewsSubject.GetPresentation() method and I’m hoping it will always work. The architecture is build in such a way, that one ModelElement can have multiple shapes, but I didn’t saw such a configuration until now, so I assume there will be only one shape.

After holding the shape in my hand I need to know something about the selected Compartment Entry. This becomes a little bit complicated, too: Sometimes I need the entry right below the mouse cursor (for CanAcceptSource()) and sometimes the entry that was below the mouse when the user pressed the mouse button. Of course a Compartment Shape doesn’t provide any of that information. Take a look at CompartmentMouseTrack and ICompartmentMouseActionTrackable in the CompartmentMapping library and you will see in which way I handle mouse events of the shape to track all these mouse actions for the Compartment Shapes that are under the control of my library.

With all these new information my CompartmentMappingBuilderBase can decide to allow or permit the creation of a connection. With some virtual methods, it can delegate  more details of this decision to your code (see the advanced options here).

How to trick the routing algorithm of DSL Tools

With the Connection Builder one can create relationships in the domain model but the connector inside the visual representation of your model will still be routed from shape to shape and won’t give you a proper understanding of the entry to entry relationship. So we have to change the routing in a way that the start and endpoints of the connector will be glued near to the entry on one side of the shape.

This will be done with an AddRule (CompartmentMappingAddRuleBase) every time a new connector will be added to the diagram (and when opening a saved diagram).

After determination the favored points on the shape outline you can set them to the connector with the FromEndPoint and ToEndPoint properties. Don’t forget to change the FixedFrom and FixedTo to VGFixedCode.Caller as well.

Don’t get tricked by the routing algorithm

If you change the start and endpoints of a connector in the AddRule these values aren’t set forever.  The user could collapse and expand the compartment shape or use the "Reroute" command that is visible in the context menu of every connector. He could also move the connector or only the start and endpoints on the shape outline. If he deletes one entry that was shown above an entry with a connection this entry moves closer to the top and the connection should do the same.

With a few lines of code, we can forbid the user to change the routing of a connectors. In the connector class the CanManuallyRoute property simply have to return false.

Every time the size of the shape changes (see OnAbsoluteBoundsChanged event) I will recalculate the connection points of all connectors assigned to this shape. This event will handle a bunch of cases for me: insertion and deletion of other entries, expanding and collapsing of the whole shape and singe compartment lists and renaming of entries which can cause reordering of the compartment list.

Delete propagation

The delete propagation is an easy requirement. I just added a DeletingRule that keep track of the deletion of certain Compartment Entries and if one is deleted it looks for Compartment Mapping Relationships and deletes them.

It is a little bit challenging to find the relationships coming from the entry. If you want to know more details take a look at the CompartmentEntryDeletingRuleBase source code.

Upcoming article

In the last article of this series I will explain the way of removing the "Reroute" command from the connector context menu. The actual code consist only of a few lines, but the way I found the point to do it can be interesting for someone because the "Reroute" command is not proper documented anywhere.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in