Thursday, February 19, 2009

If you are looking to learn about Silverlight development, here is your chance.  Our local Microsoft Developer Evangelists are running a free full day event this Saturday featuring a good variety of information. 

To learn more or register, click here.

If you are a beginner or haven't gotten started yet, this is a great opportunity.  I'm not a beginner and my weekends are pretty busy these days.  So initially, I was going to skip this event.  But from my conversation with Dani Diaz last night, it sounds like there will be a decent range of information here, so I think I will attend too. 

I don't know the full agenda but some of the speakers include Dani, Lindsay Rutter, Bill Wolff and Pete Brown.  That's a good line up but to be perfectly honest, Pete Brown is the big draw for me.  I've been reading his blog since I started doing Silverlight development, this guy really knows his stuff.  One thing I've learned over time is that if a good speaker if giving a talk, even on a topic that I think I know fairly well, it is worth attending.  You never know what kind of tidbit you may pick up from them!

Hope to see you there.

Thursday, February 19, 2009 9:42:51 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Friday, February 13, 2009

One thing I really hate about doing Silverlight development is trying to search for good information on the Internet.  When I look for a solution to a problem I am having, I always run into a lot of "noise" in the form of outdated posts that aren't relevant anymore.  There are a ton of questions, answers, and sample solutions on the web from developers working with the Silverlight 2 Beta release.  I know this was all helpful information to share at the time, but a lot of it is useless now.  The problem is, sometimes you have to read the post a bit in order to figure out that the developer was on the Beta.  I've gotten to the point where the first thing I do is look at the date on the post before I read on.  What makes this even more complicated, is sometimes the information in these posts is still relevant and very helpful! 

Oh well, at least we are lucky to be developers in an age where so much information is shared among members of the community.  Can you imaging having to read manuals for all your information ;) ?  I don't mean to discourage anyone from posting.  Don't take me too seriously, I'm just ranting.

Friday, February 13, 2009 8:45:17 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Tuesday, February 10, 2009

The other day I was working on a Silverlight app when I got this error:  Layout Cycle Detected.  The good news is that Silverlight actually gave me an error message that meant something.  That is unusual for Silverlight.  Of course the message didn't tell me what caused it, or how to fix it!  Luckily, there is this thing called the Internet ;-).  I found some information on David Yack's blog (I don't know him) that helped.

It turns out that Silverlight doesn't like it if you put too many TextBoxes in a ListBox (or possibly any other "repeater" kind of list control).  I'm not sure why it only applies to TextBoxes and not other controls, but here is my understanding of the problem...  Each time you add a TextBox to a ListBox it needs to figure out how much space to give the control, as well as all the other controls around it.  It figures that out, and then sizes all of the controls that don't have specific sizes set, and then lays everything out for you.  But I guess in a list, it needs to do this over and over and over again and Silverlight thinks it has gone into an endless loop, so at a certain point it cuts it off and says "Layout Cycle Detected".  Each time a control gets resized, the controls around it get resized, and that goes on and on until you get to the top level control.  I guess I can understand that it could be a problem, but I think the developers at Microsoft have got to come up with a better way to resolve this.  If I want to put a lot of TextBoxes in a list, I should be allowed to do so!  Also, the limit is supposedly 250 TextBoxes, but I am pretty sure I had less than that.

There are a few ways to get around the problem, as far as I know.  In my case there are a bunch of controls that made up the DataTemplate for my ListBox.  Since they are in a StackPanel, I put a fixed size on the StackPanel.  That prevents the "bubble up" of resizing going all the way to the page level.  That seemed to fix my problem most of the time, but not all of the time.  I could probably have kept playing with the layout and putting fixed sizes on more panels.  Instead, I gave in. 

I didn't want to fight with Silverlight any more so I changed all of my TextBoxes to TextBlocks.  Then I set the the ListBox items up so that you can switch them into "Edit Mode".  The problem here is that the ListBox doesn't have built in support for that.  So here is how I did it.  By the way, this is not dependent upon the "SelectedItem" in the ListBox, so you can have multiple items in EditMode at the same time.

The purpose of my list is to display a list of Services to the user.  My ListBox is bound to a collection: ObservableCollection<ServiceListItem>.  ServiceListItem is just a class that represents my data.  Among it's other properties, the ServiceListItem has a property for IsInEditMode.  It is nothing fancy:

            public bool IsInEditMode
            {
                get { return _isInEditMode; }
                set
                {
                    if (_isInEditMode == value)
                        return;
                    _isInEditMode = value;
                    NotifyPropertyChanged("IsInEditMode");
                }
            }
            private bool _isInEditMode;

In my DataTemplate for the ListBox I have two StackPanels, one for ReadOnly mode and one for Edit Mode.  The ReadOnly template has a button to switch to EditMode.  The EditMode template has two buttons.  The Cancel button reverts the data to it's original state and switched to ReadOnly mode.  The Save button saves the data and switched to ReadOnly Mode.  Here is the one that puts the template into Edit Mode (nothing fancy here):

<Button x:Name="EditService" Click="EditService_Click">
    <Button.Template>
        <ControlTemplate>
            <Image Source="../images/pencil.png" 
                   Height="10" 
                   Width="10" 
                   Cursor="Hand" 
                   VerticalAlignment="Center" 
                   HorizontalAlignment="Center"/>
        </ControlTemplate>
    </Button.Template>
</Button>

The code for the button click is pretty simple too:

        private void EditService_Click(object sender, RoutedEventArgs e)
        {
            ServiceListItem item = (ServiceListItem)((Button)sender).DataContext;
            item.IsInEditMode = true;
        }

Actually, the only cool part of this is how the control figures out which StackPanel to display.  Each one has it's Visibility Property bound to the IsInEditMode property!

                           <StackPanel x:Name="EditPanel"
                                       Visibility="{Binding IsInEditMode, Converter={StaticResource BoolVisibilityConverter}}" 
                                       Orientation="Horizontal" Height="20" >

The trick is the Converter.  We're using a Converter that converts a boolean value into a value from the Visibility Enumeration:

 

    public class BoolVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()) || !(bool)value)
                return Visibility.Collapsed;

            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // we don't need it to convert back but we could implement that later.
            return value;
        }
    }
Don't forget to add the Converter to your user control's resources:
    <UserControl.Resources>
        <ClientUtilties:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
        <ClientUtilties:BoolInverseVisibilityConverter x:Key="BoolInverseVisibilityConverter" />
    </UserControl.Resources>
And it all just works!
From this, you should be able to figure out the other end of this, switching back to Read Only Mode. 
I hope this helps.  
Tuesday, February 10, 2009 10:01:36 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, January 27, 2009

If you are working with LINQ to SQL, you may be familiar with this exception message:

"Cannot add an entity with a key that is already in use."

This typically comes up when you are working with LINQ to SQL, as I am, in a "disconnected " situation.  In my case, I am working with a Silverlight Application, so I get some data with one DataContext, then pass it out to my Silverlight application (this is the same with any other web application), make changes to it, pass it back to the server where it gets updated using a different instance of my DataContext.

The interesting thing in my case is that I thought I fixed the problem but I still got the exception.  I'll explain why.  But first, there are several ways you can resolve this issue.  How you choose to fix this will have to do with how your database is set up initially.  I am working with an existing database and there are limits to how I can change the db.  So I have my all of the properties in my LINQ to SQL Entities set as "UpdateCheck = UpdateCheck.Never".  Next I'll "Attach" my entity to my DataContext  but before I do that, I'll "Detach" it  My Detach() method "resets" all of the EntitySets and EntityRefs connected to my entity so that LINQ to SQL doesn't think I am trying to insert them into the database.  Sorry, I'm not going into details on this process in this blog post but you can easily find details on the web.  Now I can attach my disconnected entity to my DataContext like this: 

            using (ABCDataContext db = new ABCDataContext())
            {
                foo.Detach();
                db.Foos.Attach(foo, true);
                db.SubmitChanges();
            }

This should work fine.  But it wasn't working in my case.  Why?  It is a typical case of how various steps I took to resolve the a different problem ended up causing new problems.  I was debugging and trying a bunch of stuff because my calls to Attach were throwing exceptions.  There is an overload to the Attach() method that would look like this -- db.Attach(newEntity, originalEntity)  -- so that LINQ to SQL can compare the two items.  I had been playing around with it but when I commented out my code, I forgot to comment out one line, so it looked like this:

            using (ABCDataContext db = new ABCDataContext())
            {
                foo.Detach();
                Foo oldFoo = db.Foos.SingleOrDefault(f => f.FooId == foo.FooId);  // NOT REMOVING THIS LINE CAUSED THE EXCEPTION!
                //db.Foos.Attach(foo, oldFoo);
                db.Foos.Attach(foo, true);
                db.SubmitChanges();
            }

When I run this, I get the exception "Cannot add an entity with a key that is already in use".  For some reason, even though I wasn't working with "oldFoo", LINQ to SQL didn't like the fact that I requested it from the database.  So I commented out that line (Foo oldFoo = db.Foos.SingleOrDefault...) and everything just started working fine. 

It was a pain but it is over now.  Now it is time to solve more problems...

Tuesday, January 27, 2009 10:10:34 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, January 18, 2009

As an ASP.Net developer, one of my favorite tools is Firebug.  Generally, my default browser is IE, but when I develop web sites I always debug and test with Firefox with the Firebug Add-on to make designing the pages easier. If you are a web developer and you aren't familiar with Firebug you must check it out.  It basically allows you to inspect your page in the browser at runtime.  With Firebug you can see how your ASP.Net Code gets rendered into HTML, and how the CSS is applied.  Often it was not as I expected!  You can even modify the html, CSS and JavaScript at runtime.  This is a great help because you can tweak the page in the browser to look the way you want and then go back and apply the changes to your source code.

Now I am developing a Silverlight Application.  The learning curve is steep, working with XAML I am starting from scratch.  It isn't like HTML at all and it is not so easy to make controls look like you want the to.  And it was even harder because I didn't have Firebug to help.  Searching the Internet, I found Silverlight Spy.  This is a cool, free tool that helps in many ways with Silverlight Development.

With Silverlight Spy you can inspect your XAP package, monitor events, network activity and performance and more.  But the best part is that I can inspect the elements within my XAML at runtime and even make changes.  This is pretty important because I find that the XAML design experience in Visual Studio is less than perfect.  I've already used Silverlight Spy to help me solve a bunch of problems.  The tool isn't perfect, but it is BETA software and it is free, so I am not complaining.  Many, many thanks to the developers.

 

Sunday, January 18, 2009 9:20:44 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, January 13, 2009

Sometimes strange things happen.  It happened to me, I figured it was a fluke.  But last week it happened to my co-worker too.  Weird right?  Everything was working great with my VS Solution including a Silverlight App.  It isn't new and I've debugged it many times.  But for some reason, no matter what I did, the debugger seems to be ignoring my breakpoints.  At first I thought that maybe the code wasn't getting called, but it sure seems like it was getting called.  If you find yourself in this predicament, here's all you need to do.   Go to the Property Pages of your Web App (the application that hosts the Silverlight).  You get there by right clicking on the Web Application in the Solution Explorer and select Properties.  Then choose the "Web" tab and you'll see the one below.  If debugging doesn't work, the "Silverlight" checkbox is probably not checked!  I'm not sure how this setting gets reset, but at least it is easy enough to fix.

Enable Silverlight Debug

 

Technorati Tags: ,
Tuesday, January 13, 2009 8:35:02 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, December 18, 2008

So I'm working with Silverlight these days.  It's an excellent technology but it's got a fairly steep learning curve.  For the past several years I've been working predominantly with ASP.Net.  As a matter of fact, I've really gotten pretty good at it!  In addition to all of the in's and out's of ASP.Net, including the page lifecycle, custom controls, etc, I had gotten really comfortable with CSS and I've even stopped saying "I hate JavaScript" and started liking it.  Of course, with JQuery, it is really pretty good to work with.  But I digress.

Anyway, all of that stuff I have learned is out the window now.  Silverlight is completely different.  The easy part is that all of my C# code goes right to the client, as well as running on the server.  So much for JavaScript.  But there is no HTML, no ASP.Net controls.  None of it (at least in the apps I am writing).  This is not an ASP.Net application with a little Silverlight mixed in.  The entire UI for this business application is Silverlight.  The only html/asp.net is the page that hosts it.  So all of the UI is written in XAML.  XAML is cool and very powerful but takes getting used to and when you start with it, you are starting from scratch.  It's not like writing a web app or a windows forms app at all.  But don't get me wrong, I like it.

Anyway, the purpose for this first Silverlight post...

So I'm working along and things are going good.  My app is coming along and working as well as it should in the very rough state it is in.  After making a bunch of changes I fire up the debugger and run my Silverlight application in Internet Explorer.  "Hmmm, that's weird, it shouldn't do that" I think to myself.  I checked the code, and sure enough, it should not do "that".  So I run it again. Same result.  My code is running without the recent changes I made.  Ok, I try a bunch of stuff, not necessarily in this order: Build my Solution, "Rebuild" my solution, "Clean" my solution, put obvious changes in my UI and re run it, restart Internet Explorer, Ctl-F5 to clear IE, try Firefox, close/reopen my solution, close/reopen VS2008, reboot my machine.  I probably tried a few more things but no matter what I did, the application continued to show the UI before my changes.  At some point in all of this, it became clear that my XAP file was not getting updated in my web project.  I tried deleting it, figuring that would signal Visual Studio to replace it when it builds again.  No luck.  I manually placed a current XAP file (from the Silverlight app) into my web project.  Now when I run my application is perfectly up to date!  So I am positive on the problem but unsure how to fix it. I figured that in my Property Pages of my Silverlight Application I'd find something telling me where/when/what to do with the XAP file.  But I couldn't find it.  Next I searched the Property Pages of my Web Application.  Presto, there it is!  From a web application, select the "Silverlight Application" tab.  When I did the list of projects was empty!  I have no idea how it got to be that way.  But I clicked "Add" and the rest was self explanatory.  I picked my Silverlight project and selected where I wanted the XAP file to go. 

 

image

Technorati Tags: , ,
Thursday, December 18, 2008 9:04:51 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback