Tuesday, April 29, 2008

Silverlight 2 TextBlock Responds to Mouse Events when Truncated

ANOTHER UPDATE: I received confirmation from Joe Stegman that yes, this is indeed a bug in Silverlight 2 Beta 1 but has been fixed in the forthcoming Beta 2.

UPDATE: This behavior can be fixed by adding a clip to the bounding control which in this case is a Rectangle.

I finally had time to sit down and really debug the Silverlight animation problem I described in a previous post.  I recommend heading over there and reading that post, it also displays the problem in action.

The issue is that when using the Height or MaxHeight properties to restrict a TextBlock, if the text is longer than is allowed by the defined size, even though visually the text is truncated, the area in which the text would be still responds to mouse actions.  It does not matter if the properties are set on a parent object like a StackPanel or on the TextBlock itself, the issue is the same.

Unless I'm missing something if the text is visually truncated, the non-visible area should not respond to mouse events.  If anyone knows of a reason for this or a way to fix it, please let me know.

Below is a sample app demonstrating the problem.  To see the grid working normally, move the mouse around and watch the squares change color.  What should happen is that the square that the mouse is in turns red, and when the mouse leaves the square goes back to green.  If you click an item so that the text changes, then the mouseover action changes.  Now the area about two and a half squares below the selected one will also turn the square red instead of the square that the mouse is over.  If you click the square again to set it back to normal, it acts as it should.

You can download the code for the example from here.

Friday, April 25, 2008

Silverlight 2 Beta 1 Problem with Animations on User Controls

YET ANOTHER UPDATE: I received confirmation from Joe Stegman that yes, this is indeed a bug in Silverlight 2 Beta 1 but has been fixed in the forthcoming Beta 2.

ANOTHER UPDATE: I found what is causing this, you can read about the exact cause and download sample code in a newer post.  If this is a bug in Silverlight or if there is a nuance with the TextBlock of which I'm not aware has yet to be determined.

UPDATE: This is most likely NOT a bug in Silverlight itself but probably has something to do with how I am implementing it.  I will post a detailed description of what caused it and how to avoid it as soon as the cause is identified.

Let me start by saying that this issue is one that I doubt will be seen by many people, even if it does persist into the RTM version.  Even describing this issue without using lots of pictures (or better yet a (mal)functioning sample) is not an easy task, so let me see how well I do.

Background

As I said in a previous post, I started a CodePlex project to build a session scheduler in Silverlight.  Within this application there is a User Control defined that represents a single session which includes the information about the session, the graphical representation of that data and an animation.  When the app reads in data from an XML file it creates a number of instances of this user control in specific locations in a Grid.

Matt Casto joined the project this week and the first thing he did was to create a more elegant way to catch the MouseEnter, MouseLeave and MouseLeftButtonDown events by adding them to the user control declaration tag instead of to the transparent rectangle that I had been using previously.  This made for a nicer experience as the area that handled the events would expand with the control during the animation.

Issue

From the picture above you can see what the animation looks like in it's final (open) state.  When in this state, there is a path that overlaps a section of another instance of the user control below the currently active one.  With the new behavior if you move the mouse into this path covered area of the active user control, nothing happens since the mouse is still within the defined area of the user control.  So far this is all good.

The problem arises when you have one instance of the user control in an open state, then move the mouse into the area of another instance of the user control that would be covered by the expanded path.  The area I'm talking about is the top/left part of the small version of the control. 

The result is that if ANY animation is in it's open state, the instance of the User Control that would be covering that section is activated, not the instance of the control that the mouse is actually over.

Finally

I've reported this issue to Joe Stegman and may also post it to the forums at silverlight.net.  If I hear from Joe or someone else that it's actually a problem with our code and not a real Silverlight 2 bug, I'll gladly update this post with that information.

This one is most likely a rare issue that will not effect the vast majority of Silverlight applications, but it does appear to be a real issue.  For our application we decided that we can live with the odd behavior but for a business application that would be a hard case to make.

Thursday, April 24, 2008

Review: Cleveland C#/VB.NET SIG 4/22

sig_logo Once again this review is coming a couple days late, I'll try to get a little more punctual but since I've been working on that for decades, don't count on it any time soon.

First, the venue/crowd.  It was held at the Berbee office in Brecksville as usual, although most likely for the last time.  Sam Nasr, who coordinates this SIG, is leaving Berbee so will be looking for a new location (if you want to host it contact him through the site above).  The room was fine although it looked like we were about at max capacity for the room with around 30-35 people.  Pizza was a little late but no one seemed to mind, at least not that I noticed.  It also got a little warm but with that many people in a small room that is to be expected.  And they were all staring at me, so maybe I was the only one warm.

This month at the Cleveland C#/VB.NET SIG the presentation was Silverlight 2 in ASP.NET presented by well, me.  This was my first time giving a presentation like this in a long time so I was a tad nervous that day.  Ok, more than a tad, I was VERY nervous. I felt like my presentation was weak and that I wasn't ready to give it.  I may be my harshest critic (at least I hope so) and in thinking about it later I definitely have some things to work on, but overall I think people learned a lot from the presentation.  I actually surprised myself with the number of questions that I actually knew the answer to, and there were a lot of questions.  Lots of questions.

What did I do wrong?

  • I was unorganized
    • I had notes to keep me on track but didn't follow them
  • I let questions derail me
    • I would go too deep into an explanation and had a hard time getting back on track
  • I didn't prove my thesis
    • I don't know that anyone noticed this until I pointed it out over beer.

The good part about everything that went wrong is that I know how to fix it. Practicing in front of real people will help quell the nerves and let me pay attention to my notes.  Practice will also help me handle off-the-wall questions better.  A small change in my slides and a more focused demo will prove the thesis better.

Overall the feedback I've been getting from people is that is was a very good presentation.  Personally I know I have a lot of room to improve, but you have to start somewhere.

P.S. Go register for Cleveland Day of .NET, I'll be posting some exciting updates about that event soon.

Sunday, April 13, 2008

Silverlight Session Scheduler at CodePlex

Guitar2 As many of you know, I am one of a group of local developers that is organizing Cleveland Day of .NET, a free one-day developer conference on May 17th.  As part of this we wanted a cool way to allow for registrants to select the sessions they want to see from the conference website.  Naturally when the words "cool" and "web" are in the same sentence, Silverlight comes to mind.  So I built one.

Description

What I came up with is a simple way to view and select sessions for a one-day conference.  I hope to expand it to multi-day capable eventually.  It marks your selections and also shows them in a list to the side.  Eventually I would like to make it easy to print and submit your selections back to the server.  None of that is in it yet but still, I think it is kinda cool.

scheduleshot

The above image is just a screenshot.  The actual one does some neat stuff though, like an animation on mouseover to display more information.

expanded

And when you select an item, two things happen: 1) an overlay with "Selected" is placed on the box and; 2) The title is added to the proper place in your schedule list.

selected

Open Source

In the true nature of Cleveland Day of .NET, I've posted the entire source for this app at CodePlex under the name Conference Session Scheduler.  Feel free to join and help me add more features or fix what's there.  You can also just download the code and use it as is if you want to, the choice is yours.  This is a good project to learn about User Controls, global variables (i.e. singleton object) and loading objects based on XML data. 

I'll pass along one tiny piece of code in this post:  How to set a Fill color from a string color value in code.

this.myRectangle.Fill.SetValue(SolidColorBrush.ColorProperty, "#FF386E1B");



I know the above looks simple but believe me, finding it was anything but easy.




Sample




If you have the Silverlight 2 Beta 1 plugin installed you should be able to see the scheduler in action.  I won't promise to keep this up to date as we update the code but at least it is as of 4/13.

Ok, so this is already out of date but I promise I'll replace the one in this blog with the real Cleveland Day of .NET schedule when it is posted next weekend.





  kick it on DotNetKicks.com

Friday, April 11, 2008

Silverlight 2: Custom Controls vs. User Controls

Silverlight_Logo_thumb In my first post on Silverlight 2 I concentrated on how to use User Controls in a Silverlight application.  Since I started writing this post, Scott Guthrie and numerous other developers have also written posts on User Controls.  One thing neither of them cover though is when to use them.  With most technologies there are numerous way to accomplish many tasks, Silverlight is certainly no exception and one example of this comes in the form of User Control vs. Custom Control. 

This post is different than my other Silverlight posts as I'm not showing any code and don't have a cool example to talk about.  This post is meant to be more of a discussion on the differences between User Controls and Custom Controls as well as some guidance on when to use one over the other.  Much of what I'm writing here is just opinion though so if you have a different though or if you find something that I have completely wrong please comment.

Definition

First off let me say that I haven't used Custom Controls much yet so that may sway me a little but I'll try and be open minded.  I'll also say though that it does appear that creating a custom control in Silverlight 2 is significantly easier than creating a custom control in ASP.NET.  Much Easier.

Custom Controls and User Controls both accomplish many of the same goals although in different ways.  It seems to me that this question is nearly the same in Silverlight as it is in ASP.NET, and I suspect with much the same answer.

User Controls

The Silverlight documentation gives two reasons for creating a User Control:

  1. To separate functionality into smaller, manageable pieces of logic that can be created independently from an application and other controls.
  2. To group related controls that can be used more than once in an application.

In practice, user controls are used extensively for both of the reason listed.  One of the great things about them in the ASP.NET world, and now in also in the Silverlight domain, is the ease with which they can be created and reused.

Custom Controls

Custom controls can be loosely defined as creating a control that is based on (i.e. derived from) an existing control and extends its functionality in some way.  Some reason they may be built are to add a capability not included in the base controls, make a company specific version of a control or to group several controls together to perform a specific function.  This last version, grouping several controls to perform a specific function, where the big overlap with User Controls occurs.

One other advantage of custom controls is that since they are compiled into a .dll, they can be reused in multiple Silverlight applications where a User Control is limited to the application in which it is created.

Scenario

While I was working on a new Silverlight 2 project a few weeks ago I had this scenario:

I want multiple blocks to have the same base behavior, such as being resizable, moveable and a similar look/feel.  However, I wanted the contents of these blocks to be different.

With the custom control vs. user control question I went to what is becoming an incredible resource when you are looking for advice but not big text references: twitter.  I happened to know that at least three recognized Silverlight experts (TheADOGuy, LBugnion and WynApse) were on twitter at that moment and that they were following me so I sent a question which resulted in the following conversation (minor editing for clarity):

johnnystock SL2 gurus: If I want to make a custom container object to handle things like drag/drop, look/feel etc. should it be user or custom control?

LBugnion @johnnystock Does your container have an intrisic look&feel, or is it going to change its look often?

TheADOGuy @johnnystock I suggest you derive a custom control from "Panel" but not knowing all your req's that might not be perfect

johnnystock @LBugnion Look/feel will be same for all instances

johnnystock @TheADOGuy Is there a SL2 panel? I was thinking of deriving from Canvas

LBugnion @johnnystock I use UserControls when the look&feel of my control is more or less similar (changes can be handled by styles)

LBugnion @johnnystock and CustomControl for truly lookless controls, where L&F changes a lot depending where they're used

LBugnion @johnnystock That said, the sugestion to make a custom Panel sounds pretty good!

johnnystock @LBugnion That's what I like to hear as personally I find User Controls easier than custom controls :)

LBugnion @johnnystock If you check MIX sessions, Robbie Ingebretsen shows how to create a custom WrapPanel. A good start for what you do

LBugnion @johnnystock Custom Controls are harder to understand, but flexibler to use.

johnnystock @LBugnion cool, thanks for the tips and I'll check tat session out

LBugnion @johnnystock but I do a lot with UserControls too.

TheADOGuy @johnnystock Yes, its the abstract class under all the containers...look at the class def of Canvas in the .chm...

LBugnion @johnnystock The session is Nerd + Art, around 00:46:00

From the above discussion it doesn't really look like there is always a clear cut line on when one type of control is better than the other.  Well, I think there are cases where custom controls are clearly correct, and cases where user controls are clearly right, but there is also a quite large overlapping gray area.  The gray area is seems mostly populated by container controls as well.  It seems like developer preference definitely plays a major part in the decision when in the gray area. 

For what I'm trying to accomplish I will probably be using both.  The functionality will be broken into user controls but the container that houses that user control will be a custom control.  In fact, the only reason I'll be using user controls at all is to reduce clutter and make multi-person development easier as the functionality will not likely be reused.  In my opinion those are valid reasons to use a user control, even though they are not the stated purpose of them.

Conclusion

I am by no means an expert on custom controls but I do have a lot of experience with User Controls and for me I don't know that there is a simple line to choose between here.  Personally I use something like this to help make the decision:

  1. Will this control be used in multiple applications? - probably Custom Control
  2. Is there a base class that has the majority of the functionality needed? - probably Custom Control
  3. Is rapid development a factor? - probably User Control
  4. Am I building it or just specing it out? - probably User Control if I'm building
  5. What am I more comfortable coding myself? - User Controls

Does anyone else have any criteria they use?  I'd love to hear feedback on your preferences as well.

 

UPDATE: Laurent Bugnion has posted a nice article explaining how to bundle a Silverlight User Control in an assembly to use across applications.

Digg!   kick it on DotNetKicks.com

Thursday, April 10, 2008

Review: Cleveland .NET SIG 4/8

So I'm a couple days late in writing this, but it's ok, I took notes :).  Overall this was a good SIG, would have been better if I actually cared about BizTalk though. 

Why Review

First off let me explain for a second why I feel like I need to write a review of these events.  Personally I think I get two things out of writing these.  First is the chance to tell others that didn't attend about all the cool stuff they missed out on.  I think this is a great way to advertise future events by talking up past ones.  The second thing gained is that by analyzing the past, we can learn things about the future (can you tell I was a history major at one time?).  In this case, by looking at what went right and what didn't, we can come up with ways to improve in the meeting next month.  Or someone from Kalamazoo or Austin or Sacramento might get ideas for their own use group.

Venue

The venue was the Cleveland Microsoft office in Independence (notice, not actually in Cleveland) and we had both Developer Evangelist Jeff Blankenburg and Architect Evangelist Brian Prince.  This was Brian's first SIG/UG trip to Cleveland since becoming a softie.  The usual pizza and Coke was present as was the worlds worst collection of giveaways in the history of SIGs, but more on that later.  The only venue related issue was the A/C needed a kick in the pants which Brian was happy to provide.

Community

This month Richard Broida gave a talk titled "The Intelligent Programmers Guide to BizTalk" and if you remember last month's review he talked about tying to get the crowd more involved.  First on the crowd involvement.  I will give Richard credit, he definitely tried to mix it up and for the most part I would say it worked.  Nothing is going to change completely overnight but this was a good first start.  Some of the things he tried were being more conversational, walking among the crowd a bit and joking around.  Also he didn't jump straight into the talk, he started by introducing the MS guys and asking for announcements, which of course I had one.  I got up and spoke for a few minutes about Cleveland Day of .NET trying to get people to register, speak or sponsor.  Jeff even got up to encourage people to speak.  Overall between the numerous people talking at the beginning, Richard joking around and his walking around, it really did get people more involved.  Personally I think there is more to do in that arena but this was a very good step in the right direction. 

Another step in that direction of course is the after-party.  This month we had 14-15 people, not bad.  We had a few people that were new to the bar and had no previous connection to anyone in the group, which indicates it isn't becoming a 'click' but that others do feel welcome.  Once again I left way too late but enjoyed every minute of it.  Poor Brian had to drive all the way to Columbus after the bar, which we didn't leave until 11:00PM.

Presentation

Honestly I can't really judge the quality of the presentation as I'm not a BizTalk person.  At all.  Don't want to be one either.  One thing that I think came up at the bar was bullet points.  If you've read Beyond Bullet Points, well, it says to basically not use them.  I counted 27 bullet points on one of the BizTalk slides.  Now I'm not going to say that's bad since that is the norm for presentations today.  Two things about the presentation that I didn't like: 1) it felt like too much information for one presentation 2) there wasn't a break in the middle.  Any talk that long needs a break to let people stretch and socialize in the middle.  As I said, I can't really speak to the content but judging from the questions presented, Richard does know his stuff and showed numerous features that interested people.  I did learn one cool thing: functoids.  Not exactly sure what they do but it just sounds cool, Functoids.

Wrapup

I said earlier that the giveaways were well, bad.  Not all of them but overall, it lacked.  There was a backpack I thought was kinda cool, a couple copies of Halo 3 and, get this, two Windows Mobile Berets.  That's right, a beret with a MS Windows Mobile logo.  Wow.  The drawings started as you would expect, first a copy of Halo 3, then the backpack.  Next was something I don't think I've seen before, the next person 'passed'.  He didn't want anything that was left (Halo or Beret).  The next couple people also passed.  Finally someone took Halo, then the first beret went.  Then a couple more passed until finally Jeff just gave the remaining beret to the first person that would take it.  That person happened to be Joe Fiorini and he wore it all night at the bar.  Jeff took a picture of Joe in the beret, he's probably going to pull it out at an opportune moment.

Overall it was another good SIG and a good after-party.  Less than two weeks until I talk at one of these, hopefully I'll be ready :).

Wednesday, April 2, 2008

Silverlight 2: Simple Animation

I'm not a designer.  Would have trouble even opening a professional design or animation tool.  But even I can make animations in Silverlight using Expression Blend.

Now, I didn't build anything big or fancy, but I think it's kinda cool.  Most of all, I did it all myself with no help from designers or even the web or help files.  I did 99% of it within the Expression Blend 2.5 environment, only had to go to Visual Studio 2008 to wire up an event handler, and that was only a one liner.

So, who is ? Click his name to find out. (If you see the download Silverlight logo or a blue bar instead you need to do that first).  Then click the name.

Did you click it?  Go ahead, do it, I'll wait.

So it's not big and fancy but it does show a neat effect you can use Silverlight for.  It's also a great example of using Silverlight for a very small piece of a page as opposed to the full RIAs that are being showcased.  I uploaded this tiny app to Silverlight Streaming to allow me to use it in this blog where I don't have access to the server or even the header of the page.  As you can see it works :).

How did I do it

I only had to touch two files for this little app, page.xaml and page.xaml.cs.  I did cheat a little bit by using a mono-spaced font to make the letter positions line up at the same location regardless of the letter width.  If your not sure what I mean take a look at these sets of letters in two different fonts:

iiiii
wwwww
iiiii
wwwww

Can you see how in the second font the letters are all the same width where in the first there is a very noticeable difference?  By using the mono-spaced font I was able avoid spacing issues.  Did I need to, no, but it made it easier.

Create the objects

Using Expression Blend 2.5 I created a Silverlight 2 Application that gave me the basic page.xaml and app.xaml files.  I then got right at creating the xaml objects.  First I replaced the default Grid root control with a Canvas instead.  I may not have needed to do this but since I was dynamically placing them and not using columns or rows, it seemed appropriate.  Next I added a rectangle to fill the background.

Xaml_canvas 

Again, I could have completely skipped this step and had a transparent background, but I know it was going to be on a white page so it made sense.  I then added a separate TextBlock for each letter each of which with the exact same height, width and vertical placement.  They were all exactly the same distance apart as well.

Xaml_Textblock

I then added a rectangle over top it all to act as the clickable area.

xaml

Build the animation

BlendInteractionWith all of the xaml objects created, I could start on the animation.  Again using nothing but Expression Blend, I first created the storyboard.  Then I selected the first letter (TextBlock) and added a keyframe at 0 seconds and another at 1 second.  I then selected the letter and drug it to it's new location.  Using split view when editing animations helps so you can fine tune values.  This made getting the letter to the exact spot I wanted quite easy.  To make the letters flow a little nice I added a couple more keyframes immediately after the first and before the last.  On to these I set the opacity of the textblock to be 65% and on the first and last keyframe I set made sure it was at 100%.  Running it a few times I was satisfied with the look so I then followed the same process for each of the other letters.

One thing that happened during this I found odd:  Even though I followed the same process for animating each TextBlock, the first half of them modified the Canvas.Left property while the others applied a RenderTransform along the X axis.  Both approaches bought about the same result but I still would have changed them to all be the same in a production application.

Wire the event

The only thing left was I needed a way to start the animation.  For this I selected the final rectangle and in the properties tab I selected the events pane.  Once there all I needed to do was double-click in the MouseLeftButtonDown text box and Visual Studio 2008 opened with the page.xaml.cs file open and the stub method already created.  Then it is as simple as calling the Begin method on the storyboard.

VS_mouse

I did do one other thing in code actually and that was in the constructor for Page, I set a couple of properties on the storyboard to get the reversing behavior and the pause between directions.

VS_Prop 
That's all there is too it.

kick it on DotNetKicks.com