Saturday, June 26, 2010

Ken Levy on Servoy in Europe

Sounds like Ken Levy is really getting big on Servoy and convincing VFP developers to look into it. Fresh after his Servoy webinar.

Details for a special seminar on July 5th in the Amersfoot, Netherlands are available here.

Eric den Doop : VFP Developers from Europe are invited at 5 july 2010 at the Servoy HQ in Amersfoort - Netherlands

Thursday, June 24, 2010

Mindmapping with iThoughts, MindManager and Box.Net / DropBox

I love it when I find an implementation of technology that has likely existed for a few years but works (almost) seamlessly the way I need it to. I may have missed it the first time out but it's still important to let people know how they might find it useful.

iPhone Mindmapping with iThoughts

I've spoken about Mind-mapping and MindJet many times before.

MindManager is a great tool but when I'm in a short client meeting, I don't always like to pull out my notebook. For the past year, I've been using iThoughts on my iPhone and really enjoying how well it integrates with MindManager, using its innovative "transfer" capability (it creates a web server on a Wifi connection and gives you a web page to upload and download files).

MindJet's iPhone interface is remarkably similar to the iThoughts interface - almost to the point of it seeming like a direct copy or re-licensed version.

However, when my iPhone was upgraded to iOS 4.0, it also upgraded all of my applications, including iThoughts to version 3.0. The refreshed interface is wonderful - including in-line editing and more.

What impresses me the most is the integration with Box.Net, which has been around for a while. I created a free account and uploaded some of my MindManager maps. I then opened my files in iThoughts on my iPhone (no conversion necessary), made changes and synchronized. The files are all updated. I could then make changes in MindManager and sync them directly over the web.

The downside is that I can't synchronize a Windows folder with Box.Net (or if I can , please let me know how). Mesh does this via a desktop client. If I could do that, then the circle would be complete. I could modify my map on my notebook and it would sync transparently.

There are other alternatives - I could use a web-based MindMapping tool (such as Mind42), but some of these use Flash (and thus don't work on the iPhone) or the web implementation just doesn't have all the features or are too slow.

While web apps may be the future, but until they get to the point where they can match the features and functionality of the dedicated platform apps, we will need tools like box.net and others, and thankfully, they are there to fill that void.

Update: although I had heard about it for a few years, I hadn't tried DropBox - a direct competitor to Box.net. While Box.net offers some more advanced features, for what I need, DropBox is the better solution. Thankfully, the latest version of iThoughts supports both. The real benefit of DropBox is that it *does* provide folder syncing (even though it is its "own" folder - My DropBox).

The sync between DropBox and iThoughts is amazing. I updated a Map on my laptop and then sync'd one minute later on my iPhone. The changes were there. I then did the same on my Iphone - after syncing through iThoughts, the change was there on the laptop. No time lag whatsoever. That's perfect for what I need.

Tuesday, June 22, 2010

LINQ, Reserved Names and .Net

Here's another good reason not to use reserved names.

I'm working on a LINQ project with a series of tables that manage user roles. As a result, I have table names like Systems, Roles and Users.
My trouble started when I would add the objects to the Designer, hit Save and then suddenly Visual Studio would say things like

"System.Data.Linq.Mapping.DatabaseAttribute is not defined"
or
"System.Nullable is not defined"


In short, stopping me dead in my tracks. Now that I look back, I don't know why I didn't see the reason earlier.

When using the Object Relational Designer, Visual Studio wants to be smart and changes any words that are plural to singular so they make more sense when dealing with data.


That way, your code looks like

oUser = New User
oUser.UserName = "John"

instead of
oUser = New Users
etc

This is really nice because it does make the code a little more legible except in this situation:

Plural (singular)
Users (User)
Roles (Role)
UserRoles (UserRole)
Systems (System)


See the gotcha? Visual Studio translated the "Systems" table into a "System" object which immediately negated all of the main namespaces in the project.

The renaming feature for the objects in LINQ-to-SQL is great - but be warned, when you start getting errors like this, take a look at your source tables.

Friday, June 18, 2010

Intense Development: Why We Need Passionate Programmers

At a conference a few years back, I formally met someone who I had been speaking with online for a few years. One of his comments was "wow, I didn't realize you were this intense". At the time, I was surprised as while enthusiastic about the conference, I didn't think I was being that noticeable. But I will admit - I am very intense or passionate about the things I do. I think that's very important to the developer and consulting world and far too often, it's missing.

Programming is an analytical and (supposedly) fact-based process, which is why most programmers tend to be left-brained. This discernment is more myth-based (as logical sciences such as maths are handled by both) but more creative or emotional types are said to be "right-brainers".

Today, when you need both programmers and designers rolled into one (or at least combined in a single project), this can get tricky.

As a consultant, I deal with a number of clients. Some I have had the pleasure of working with for years, while others have been shorter-lived. However, I always try to find something in their work that excites me. Yes, I'm there as a "contractor", a repairman or mercenary of sorts - but without that excitement or commitment, why would I care about doing a good job?

There are arguments for why you don't want too much enthusiasm. Being more pragmatic and analytical, you may tend NOT to make mistakes (ask any programmer after a late night session if they think their code is bug free). But you may also alienate the client or worse yourself. In programming, it's very easy to become overwhelmed with the possibilities for failure and paint yourself into a corner where all you deliver is the least-risky, least-powerful piece. That's not to say that it can't be usable but it may not deliver on expectation.

Sidebar:
(there's a reason why Apple tends to either delay products or take away features - when they deliver something that they describe as powerful or impressive or "magical", they truly believe it themselves).

If you haven't seen Steve Jobs' interview at D8, watch it. Forgetting all about the conversation about AT&T, sex, Flash and Google, there's a very interesting part about what he found when he returned to Apple 12 years ago. To summarize, he found a lot of amazing and skilled developers and he asked them "why are you still here?". The common response was that they had "six-color blood", a term that throws back to the second Apple logo. Some might say that kind of passion is more of a tear-jerky look back at history, although we have certainly seen what Apple has done since then.

End of Sidebar


I would rather have a passionate programmer or consultant than anything else. When I first meet a consultant on a job, I ask what areas of work do they "love". When asked, I'm always pretty much a "data-head" - I love data and turning it into information. Others love pure coding; others refactoring, etc - why someone who loves one area would bother taking on the responsibility of another area distresses me - because it means that there is one less person who cares about the project.

Even in a hard economy, such as this one, where people are struggling to find work, and perhaps even more importantly in such an economy, is passion necessary. You have to find a job, you have to get work - if you get it, at least be excited or passionate about it. If you don't want to do it, then get out of the way. Recently, I started at a client site with a colleague of mine. While I was consulting directly for myself, he was consulting through a parent company. While his other workload was hard, he immediately saw that he couldn't do a good job at the client site because he just wasn't interested in delivering the type of solution they wanted. He left the job within two weeks. The client may have lost money during those two weeks - but at least they weren't stuck with someone who didn't care about what they were delivering.

Early in my career, I was at a company working with a team of about 4 or 5 other guys and while I was likely third in terms of being there, I was by no means the most computer-educated or technically knowledgeable. But we all had our areas that we had to work on, and there was one section that was taking longer than the others. The guy working on it had his masters in Computer engineering but just wasn't into it. He would stare at the screen and it just didn't make sense, like the Matrix falling down in front of him. What was a relatively simple task was not getting completed. At one point, I even said "I can't think for you". The project wasn't something that I had started but it was the job at hand - it had to get done and I was intent on getting it done. I was, coming back to my first story, "intense".

I refuse to apologize for my intensity or passion on projects. I think it does a disservice to the client and to the project itself. Yes, it might be a small project in the grand scheme of things (and what isn't - unless you're really changing the world), but it's still *your* project or *your* client. If you don't care, get out of the way and let someone who does take that role.

Wednesday, June 09, 2010

Ken Levy Webinar: Servoy for Visual FoxPro Developers

For those who didn't receive the invite, Ken Levy is doing a session on how FoxPro developers can work with Servoy, a java-based development tool.

You can register here.

There's also an intro screencast you can see here.

I looked at Servoy a few years back and it looked pretty cool for development. As Ken notes in his email "Servoy is a very community oriented product with passionate users reminding me of the enthusiastic FoxPro community. " Should make for an interesting demo.

WPF: Bubbling Events from User Controls

While building a WPF application, I ran into a scenario that immediately called for a bubble event. While the basic concept behind it is pretty straight forward and there are a number of examples to show it,
when I put it all into practice, it didn't work. I got it working and it's just a little tweak but hopefully no one will spend the time I did looking for it.

Bubbled events do exactly as they sound: the event fires at a very low level and then continues up the application hierarchy waiting to be "handled".

In a traditional application, you might have a method called cmdSave_Click which handles the Click event for the Save button.

A bubbled event is more akin to button groups in VFP, where you may have four buttons and when one is clicked, the code to actually handle it is managed in the button group's method rather than the individual button click.

Take that concept and expand on it further. A real-world example that I remember Steve Black once using is Help. When user hits F1, ideally the user gets help for the one object or dialog they are on. Failing that, they should get help for the basic page they are on, Failing that, they finally get help on an entire application. The Help bubbles until it is handled.

Not a very technical description but hopefully it works for you.

In WPF, they have routed events and attached events, which is when some other function or method handles another event. This is similar to a VFP BINDEVENT(), where you write a function to manage another object's event. The difference here is that you can actually create the event in the WPF component.

So in my scenario, I've created a Navigation "pane" that appears on the left side of the application. When the user clicks an item on the Pane, the rest of the application reacts to it, going to a particular report or page, or whatever. This pane is actually a WPF user control. There are other components (like menus) that do the same thing so the logic to actually GO to another page is at the application level. In good form, of course, the Navigation pane doesn't know that, it simply knows that when the user clicks an item on it, it executes an event.

The samples you sometimes see are based on code being directly in XAML (note: the "uc:" simply points to the user control's namespace) :

(note for VFP users: the "Grid" referenced here is for the actual page layout - not the traditional data grid you may be used to)


<Grid uc:UserControl.CustomEvent="ApplicationHandlerCode">
<uc:UserControl></uc:UserControl>
</Grid>


In the above code, the User control has defined an event named CustomEvent. When the user control's CustomEvent is fired (which may be from a button or another object in the user control), the statement in the Grid element tells it to execute the method ApplicationHandlerCode, which would reside in the main application (or the control where the Grid was placed).

The code here is in VB - primarily because there are tons of C# examples and oh yeah, my client requires VB.

So using my navigation pane as the example, my user control was defined as:
Class navPane
Public Shared ReadOnly NavigateEvent As _
RoutedEvent = EventManager.RegisterRoutedEvent("CustomClick", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(navPane))

Public Sub New()

' This call is required by the Windows Form Designer.
InitializeComponent()

Me.Button1.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf Button1_Click))


End Sub
Public Custom Event CustomClick As RoutedEventHandler

AddHandler(ByVal value As RoutedEventHandler)
Me.AddHandler(NavigateEvent, value)
End AddHandler

RemoveHandler(ByVal value As RoutedEventHandler)
Me.RemoveHandler(NavigateEvent, value)
End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

Dim newEventArgs As New RoutedEventArgs(navPane.NavigateEvent)
Me.RaiseEvent(newEventArgs)

End RaiseEvent
End Event

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
RaiseEvent CustomClick(sender, e)
End Sub
End Class


The part in the RaiseEvent is the most crucial. When looking at other code samples, you will often see:

RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.RaiseEvent(e)
End RaiseEvent


For user controls, this does NOT work. You have to explicitly create a new routedeventargs instance.

RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

Dim newEventArgs As New RoutedEventArgs(navPane.NavigateEvent)
Me.RaiseEvent(newEventArgs)

End RaiseEvent


Why is this? I'm not quite sure - it seems to me that the RaiseEvent should be able to take the passed arguments but it can't. Go figure.

At any rate, in my main application, I then created my instance (dynamically) of the NavPanel and added my handler directly to it.

Dim pnlNav As New ControlLibrary.navPane

pnlNav.AddHandler(pnlNav.NavigateEvent, New RoutedEventHandler(AddressOf GotoPage), True)


Where GotoPage was my method that handled the events.

Private Sub GotoPage(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
MsgBox("Running goto page")
Window1.txbTitle.Text = "Navigating"
End Sub


As can be seen from my msdn forum request
Bubbled Event from User Control Library Not Firing, the problem wasn't obvious but the resolution works perfectly.

Once again, the key to making it work was simply creating a new RoutedEventArgs and passing THAT. If I wanted to pass specific details, I would add those to my RoutedEventArgs.


Side Note
Now, obviously most of this was done with code. Here's one example of doing something similar but using Storyboard events from Expression Blend and code. The secret behind this is that the description of the routed event is handled as a trigger:

<UserControl.Triggers>
<EventTrigger RoutedEvent="att:Monitor.Alarm">
<BeginStoryboard Storyboard="{StaticResource ShowWarning}"/>
</EventTrigger>
</UserControl.Triggers>


And this trigger runs a StoryBoard which does animation, all from within the XAML. Very cool stuff.

Wednesday, June 02, 2010

New FoxShow: Jim Nelson Interview

In the latest episode of the FoxShow, we feature an interview with Jim Nelson, who is the main project lead on the PEM Editor project at VFPX, on his history with development and how he comes up with some of the ideas he's been putting into PEM Editor.