Is true belief a good attribute of an architect

Recently I've came across this forum thread regarding the future of [DevEx]' eXpress Persistent Objects for .NET (XPO) ORM product. Customers (actual ones, not potential) are asking whether XPO will someday support n-tier development. They are happily using XPO but they miss a vital part, which is n-tier development. Note that XPO never advertised n-tier support and nobody is arguing that. Perhaps this comment from a customer's post, where the situation is described:

"As Trevor said, I am one whose core is 100% XPO. The future of my application is tied to XPO. Was this a bad decision? Maybe, but probably not. However, XPO lacks in areas (n-tier) where I really need it to start to shine."

Later on Oliver from [DevEx] comments that [DevEx] is planning to add, among various features, a multi-tier support. No other details, no dates, no nothing:

"The architectural changes we are planning will result in the potential to support a variety of layered application architectures, including multi-tier ones. So this is good news for you and everybody else waiting for this kind of functionality."

And crowd goes cheering and applauding. Can this be defined as a true belief? From the point of [DevEx] such a comment in current situation makes sense (I won't question whether XPO is good or bad and if it is going n-tier or not at this point). What I fail to understand is the crowd. How can it be that you use a product that misses a very important feature for you (from the beginning!) and you are prepared to wait for years to get it? We aren't talking about a cosmetic feature. No, we are talking about core functionality. And you are happy that somebody is planning someday to deliver that feature, which might suite you or not, without any obligation to deliver (again, I am not questioning [DevEx]).

Generally speaking, is such a belief and faith that the feature will be what you've asked for, a good attribute of an architect? Would you choose a product that doesn't support a core functionality and it might never support it. Knowing that competition is stiff and you have plenty of choices out there that support this feature and more, you are a bad architect if you don't look around. At least one I wouldn't trust. This is simply bad practice. If you are basing a core part of your application on something, it should work from the start. Gambling on future is not an option.

Righthand Dataset Debugger Visualizer goes 2008 and looses expiration restriction at the same time

As a (late) new year gift I've removed annoying expiration restriction from my dataset debugger visualizer. Find the 0.9.12 update here.

I've also rebuilt it for Visual Studio 2008 version which will be the only one supported from now on. Find the 0.9.12 version for 2008 here.

Read more about Righthand Dataset Debugger Visualizer.

Custom embedding using CodeRush

It happened that I had to embed plenty of asp.net elements into tables, i.e:

<table> <tr> <td> <asp:Label ... /> <asp:TextBox ... /> </td> <td> <asp:Label ... /> <asp:TextBox ... /> </td> ... </tr> </table>

Basically I had to put every Label/TextBox pair into its own table. The outcome has to be something like this:

<table> <tr> <td> <table> <tr> <td> <asp:Label ... /> </td> <td> <asp:TextBox ... /> </td> </tr> </table> </td> <td> <table> <tr> <td> <asp:Label ... /> </td> <td> <asp:TextBox ... /> </td> </tr> </table> ... </tr> </table>

And there were plenty of such pairs. So I was facing tedious manual repetitive work every decent developer tends to avoid at all costs. My first though was that it might be done with [CodeRush]. After all it has embedding functionality. Not only it comes with predefined set of embeddings - [CodeRush] allows you to easily create your own embeddings easily. But first let take a look how embeddings are accessible. There are two main ways. First way is through context menu in Visual Studio editor after selecting one or more lines:

image

As you can see there are plenty of embeddings out of the box. There is another way to trigger embedding functionality: through shortcuts (i.e. CTRL+3 in my VS triggers method embedding - embeds the method where caret is located in #region [MethodName] ... #endregion block. Actually I use this embedding heavily. Note also that embedding availability is based on language of the file where caret is positioned (i.e different embeddings are available for asp.net files and c# or vb.net files) and on the context (when invoking through shortcuts). But back to my problem. I actually needed two embeddings that would do:

  1. Wrap selection into <table><tr>...</tr></table> block
  2. Wrap selection into <td>...</td> block

Here is the how you add those two embeddings.

Click DevExpress/Options... menu to open Options window, expand the tree on the left to click on Embedding node.

image

Since these embeddings will work on asp.net files pick HTML as Language in combobox on the bottom of the form.

image

Click on the big green plus sign to add first custom embedding.

image

Assign name Tabloid and caption the same. Next select proper embedding style by clicking the first icon in Style row.

image

 

The final step is to type lines <table><td> above the special line Selected Text and </tr></table> lines below this special line. These lines will form embedding header and footer. That's it. It should look like this:

image

Repeat the same steps for the table cell embedding (named Celloid with caption Table Cell in my case):

image

We are done. Now let's try it on my example. First select all lines that have to be embedded into table (Label and Textbox in my case) and right click to show context menu.

image

There they are my two embeddings - FYI there are no predefined ones thus only mine are showing up. Here is the result after Tabloid embedding:

image

Do the same with Celloid embedding.

image

The result is a good one, too. Exactly what I was looking for.

image

So far this is a great time saver and annoying typing repellent. But [CodeRush] can be of more help. It is able to fire embeddings (and other stuff) through custom defined shortcuts. Mouse is great however it is not as fast as keyboard is.

Lets create the shortcuts. The goal is to bind key t to Tabloid and key d to Celloid embeddings. Open [CodeRush] options again but this time select Shortcuts tree node.

image

Click on New Keyboard Shortcut icon

image

In the Key 1 field type t (shortcut)in Command combo box pick Embed (action) and as Parameter type the name of embedding which is Tabloid in my case.

The shortcut is almost ready and the only thing left is to specify the context where the shortcut fires. If you don't set the context the embedding will fire each time you type key t wherever you are. This might be not the desired behavior. Set that the following conditions that have to be met: Selection should span Multiple Lines (one or more lines) and it should contain Whole Line. Also, the shortcut should fire only when editing in HTML View:

image

That's it. When you select one or more lines in HTML code (which includes ASP.NET) and then press key t the action Embed/Tabloid will be fired and your lines will be captured to a table.

Almost same steps are required to create Celloid shortcut on key d. Except for the context settings. Since context is the same in both cases a copy/paste operation can be performed on context. Right click anywhere in the Tabloid's context window and pick Copy Context.

image

Go back to Celloid, right click anywhere in the context window and pick Paste Context. Context is then copied and you avoid re-clicking all of the conditions (there might be plenty of them).

That's really it. I can go now through asp.net code, selecting lines and pressing t or d to embed elements.

Trust me, if you have many pages with many embeddings to perform you'll love this embedding feature of [CodeRush]. Now you can create all sorts of embeddings you want. Enjoy.

Thanks to Mark and Dustin for guidance.

Ribbon mania

I often wonder why is everybody jumping on the (Office like) ribbon wagon. Ribbon UI is clumsy if it isn't done properly and furthermore, if you ask me, it just isn't suited for all applications. So I came across this example of application:

The image is taken from this "Case Study: Itagent chooses DXperience" blog post

Honestly, I didn't read entire post nor do I know what application exactly does. What caught my eye is ribbon taking almost third of the window area - ~30% for displaying a bunch of buttons is a nonsense, bad design and a sign of ribbon misuse. It is good only if you are paid by the screen area used by your application. Again, perhaps there is more to it - a broader view, but judging from the picture I can't think of anything else. And this isn't the only application that does it - there are plenty of others.

So, if you feel like you have to use ribbon, use it wisely - not just because you have to.

Spell checker for developers is a good thing

Here is an output from Intel's Matrix Storage Console when repairing a RAID array:

image

Yep, it says Verifing instead of Verifying. This is a common harmless error that happens in an application. While it is a harmless one it makes you feel uncomfortable though - if developers are producing such obvious errors they also might ... if there is a real error in RAID driver...ouch. Isn't there an easy solution for a developer to avoid such errors?

I have a solution for developers - spell checker add-in for Visual Studio (requires free DXCore engine - a part of CodeRush/Refactor! from [DevEx]). It adds spell checking capability right into your IDE and its free!

Read spell checker description and then download the latest version from here.

Make XtraVerticalGrid fast as a bullet

Recently I've discovered that XtraVerticalGrid, a nice vertical grid from [DevEx], has some serious problems with speed when doing batch updates. Usually you should enclose batch updates within BeginUpdate/EndUpdate method calls. This usually prevents processing/redrawing within the control when one does many updates to underlying datasource at once. The neat effect of BeginUpdate/EndUpdate results in dramatic speed improvements.

However, XtraVerticalGrid doesn't implement batch BeginUpdate/EndUpdate very well and still massively processes the changes even though developer doesn't want to. Basically an operation that should take a fraction of second took more than 3s, which is an annoyance to the user, due to this problem.

Here is the workaround

Derive a class, i.e. RhVerticalGrid from VGridControl and add this piece of code:

public class RhVerticalGrid: VGridControl { private int lockUpdateCount; #region BeginUpdate public override void BeginUpdate() { lockUpdateCount++; base.BeginUpdate(); } #endregion #region EndUpdate public override void EndUpdate() { lockUpdateCount--; Debug.Assert(lockUpdateCount >= 0); base.EndUpdate(); } #endregion #region CancelUpdate public override void CancelUpdate() { lockUpdateCount--; Debug.Assert(lockUpdateCount >= 0); base.CancelUpdate(); } #endregion protected override void OnDataManager_ListChanged(object sender, ListChangedEventArgs e) { if (lockUpdateCount == 0) base.OnDataManager_ListChanged(sender, e); } public override void InvalidateRecord(int recordIndex) { if (lockUpdateCount == 0) base.InvalidateRecord(recordIndex); } }

That's it. My execution speed dropped down from >3s to almost instantaneous execution. Begin|End|CancellUpdate methods just increment/decrement lock counter (when lockUpdateCount == 0 the updates are allowed, otherwise not). The main improvements are within OnDataManager_ListChanged and InvalidateRecod methods where I propagate the processing only if updates are allowed. That's it - use the derived grid control instead of the original. Simple as that. And make sure your batch updates are enclosed with Begin|EndUpdate methods!

How does one find such culprits?

If you are scratching your head with the question "how does one find the culprit of such slowdowns"? The answer lies in performance profiling. To find this one I've used my favorite AQTime profiler (much more than just a performance profiler) and quickly found the culprit. I should also mention that this isn't the first time that AQTime helped me to find both memory and performance problems. Yep, a performance and memory profiler is a must have tool for serious developer, even better if this is AQTime. Anyway, here is clear picture (from AQTime graph view) of the culprit in action:

image

BTW, here is the link to the bug report on the [DevEx] support center I made today.

Creating SpinComboBoxEdit control

I saw a question about how to extend [DevEx]' ComboBoxEdit control to include spin down and up buttons in their forums. The buttons should cycle through available items. I thought I could easily create such a control and here it is in all its glory:

image

Note the two added spin buttons at the right side.

Now, let's test it. Here is my test data:

image

Clicking on left spin button will set the first value:

image

Next click on the same button will move the selection forward:

image

and so on.

And here is the required code

using System; using System.Collections.Generic; using System.Text; using DevExpress.XtraEditors.Repository; using System.Drawing; using DevExpress.XtraEditors.Registrator; using DevExpress.XtraEditors; using System.ComponentModel; using DevExpress.XtraEditors.Controls; using System.Collections; namespace Righthand.Editors { public class RepositoryItemSpinComboEdit : RepositoryItemComboBox { static RepositoryItemSpinComboEdit() { } public const string SpinComboEditName = "SpinComboEdit"; public override string EditorTypeName { get { return SpinComboEditName; } } public override void CreateDefaultButton() { base.CreateDefaultButton(); Buttons.Clear(); Buttons.Add(new EditorButton(ButtonPredefines.Combo)); Buttons.Add(new EditorButton(ButtonPredefines.SpinLeft)); Buttons.Add(new EditorButton(ButtonPredefines.SpinRight)); } public static void RegisterSpinComboEdit() { //Icon representing the editor within a container editor's Designer Image img = null; try { img = null; // your image; } catch { } EditorRegistrationInfo.Default.Editors.Add(new EditorClassInfo(SpinComboEditName, typeof(SpinComboEdit), typeof(RepositoryItemSpinComboEdit), typeof(DevExpress.XtraEditors.ViewInfo.ComboBoxViewInfo), new DevExpress.XtraEditors.Drawing.ButtonEditPainter(), true, img)); } } public class SpinComboEdit: ComboBoxEdit { static SpinComboEdit() { RepositoryItemSpinComboEdit.RegisterSpinComboEdit(); } public SpinComboEdit() { Properties.ButtonClick += new ButtonPressedEventHandler(Properties_ButtonClick); } void Properties_ButtonClick(object sender, ButtonPressedEventArgs e) { if (e.Button.Index == 1) MoveSelection(1); else if (e.Button.Index == 2) MoveSelection(-1); } private void MoveSelection(int index) { int? indexOfItem = null; if (EditValue != null) { indexOfItem = Properties.Items.IndexOf(EditValue); } int newIndex = -1; if (indexOfItem.HasValue) newIndex = Math.Max(Math.Min(indexOfItem.Value+index, Properties.Items.Count - 1), 0); else if (index > 0 && Properties.Items.Count > 0) newIndex = 0; EditValue = Properties.Items[newIndex]; } public override string EditorTypeName { get { return RepositoryItemSpinComboEdit.SpinComboEditName; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new RepositoryItemSpinComboEdit Properties { get { return base.Properties as RepositoryItemSpinComboEdit; } } } }

Most of the code is required to derive my SpinComboEdit control out of [DevEx]' provided ComboBoxEdit control (see 7.2 help file topic Editor Features/01.Editor Structure/Custom Editors - or previous version help file, just this link won't work).

Points of interests are CreateDefaultButton() method where I create default buttons, SpinComboEdit() constructor where I attach to Properties.ButtonClick event and MoveSelection(int index) method where I actually move the selection forth and back. It should be pretty straightforward to understand.

I hope you'll find this sample useful and take note that this code can and should be further improved as it was a quickly built with demo purposes in mind.

An easier way to populate XtraLayoutControl

[DevEx] has a nice UI layout control XtraLayoutControl that helps both designer and runtime user to design WinForms UI with ease.  One can even save and load layouts (again, both at design and runtime). This way end-user can customize the layout and perhaps persist his/her changes somewhere.

(picture taken from [DevEx] website)

While XtraLayoutControl is a real time saver and end-user source of customization happiness (not to mention that it brings down costs of development) it has some rough edges. Here are two features that can drastically improve:

  • visual inheritance support

Almost non existent. You can't change layout on derived forms. Unfortunately, dropping VI support, is a general trend inspired by [MS] itself (I posted a while ago here) and I am not sure how much can [DevEx] improve it. It would be nice to have an option to add and change items though.

  • design time support

XtraLayoutControl has great design time support, yet they are missing one feature: being able to create & bind items automatically, like VS2005's drag & drop from Data Sources window on to the form instance (did you actually know about this VS2005's feature?). So, if you have an entity with 30 properties you want to put on XtraLayoutControl you will have to work quite a lot. If you like to see this feature (and I bet [DevEx] is already working on it for some time) you can cast a vote here (issue CS19682).

Is there anything you can do to avoid there shortcomings? There is not much you can do to enhance VI support. But you can speed up layout building process. Here is what I am doing:

  1. Create a new Form
  2. Use VS2005 drag & drop from Data Source window to the form. It creates both labels and controls for me (you have to use Detail mode otherwise you'll end up with a grid). The nice thing here is that it creates [DevEx] controls by default. What's even better is that all of the controls are already bound.
  3. Drop a XtraLayoutControl on it and don't dock it.
  4. Drag and drop each control (leave label as is) on to the XtraLayoutControl and position it as you want.
  5. When you are done, delete labels and dock XtraLayoutControl  wherever you want.

This process saves me a lot of mouse actions and keyboard clicks. Do you have a better way?

UPDATE: [DevEx] confirmed that they are working on this feature. If you want to see what are they cranking just follow my suggestion report here (issue CS19682) and see their response.

CodeRush's amazing References window

There is another compelling feature brought to us by [CR] 2.1.x version: References window combined with ultra fast "Find All References" feature. Find All References* is a faster version than VS2005' feature with same name (note that [CR] supports VS2003 and I think 2002 too, thus it automatically gives you same functionality there).

While the feature is similar (albeit much faster), the output is much improved. For this purpose a new docking window, References window (found in DevExpress/Tool Windows menu) is used to display all references utilizing different fonts and color (perhaps it is just a bit too much colorful and font different) in the left window. Furthermore, it can display a piece of code around selected reference (see right window).

Did I mention that [CR]' version is much faster? In fact it is so fast that another option is possible: Live Sync (in upper left corner of Reference window). Live Sync performs Find All References in real time, when you move your caret in source code so you don't have to invoke it manually each time and you have all references display at all times. To show off [DX] included even performance information in References window status bar.

See [CR]' Find All References in action (caret is positioned over calcEdit1 variable):

(click to see normal size)

Here is also a video of new features in [CR] 2.1.x.

Personally I find References window (Live Sync all the time) of a great help to me, an another must have feature, and [CR] even more of a tool one can't live without.

*Find All References searches for all references to given variable or type in entire solution and displays the output in a separate docking window. Very handy feature.