Jaime Rodriguez
On Windows Store apps, Windows Phone, HTML and XAML

  • Jaime Rodriguez

    Inside the PDC2008 Pre-conference sessions..

    • 1 Comments

    Last week I recorded a PDC CountDown video about the Pre-conference seminars at PDC2008. 

    Going into the recording, I knew I would have to keep it very high level (since the format for the whole recording is < 10 mins and there are important PDC announcements first, so I was couting on 8 minutes, and it takes me 3 to introduce each speaker, these folks have too many accomplishments).

    Now that I have no time constraints, here is a detailed introduction to the PDC pre-cons. 
    The top part of this writing is a bit of high-level reasons why you should attend the pre-cons? 
    Underneath that section, you can find the "inside the pre-con" planning, goals, processes, and raw session details as I see them (not as the polished abstracts describe).

    <marketing>
    What is a pre-con?
    An all day training the day before PDC.

    What should you expect if you attend a pre-con?

    • Guidance! Actionable advise & lessons learned from industry & technology experts.
      Pre-cons are only a day, so when I thought about the sessions, I made sure the topics lend themselves for the presenters to share their lessons learned, their advise both on best practices and avoiding worst practices.  The motto for the pre-con from the start has been "Spend a day at the pre-con, learn some thing you can apply to your job as soon as you walk out of the pre-con!"  
    • Great/Relevant content:  
      We selected the topics very carefully to align with either PDC or the software industry.  Where we have PDC sessions on the topic (like parallelism) the pre-con will greatly compliment PDC sessions; where we don't (like Agile) the topic is very relevant to the industry.  Please do make sure you scroll to the 'inside' section to get the details on each session.
    • Great presenters:  
      The line-up of presenters is pretty incredible.  This was by far the highest priority for us, we wanted people who "do and teach" or "walk the walk" and I must say we got it.  Here are some silly statistics for you to get a measure on caliber:
      • 80% of the sessions have book authors as presenters.  If I go by numbers and add up the books I average ~two books per person (and these books are top sellers!)
      • 90% of the sessions have speakers that are regulars at big conferences (like PDC, TechEd, etc.). The only session that does not have 'repeat speakers' is "advanced debugging" and the reason for that is that we purposely went deep but I vouch for the speakers (have you read their book? ).  If you can't take my endorsement, how about Mark Russinovich's endorsement .
      • The Microsoft speakers are either Dev-Leads, Architects, or Distinguished Engineers. These are the people that "earned their stripes" and are now driving strategy; these are the kind of people I would want to get advice from.
    • Huge value
      The cost is $400. Most people pay that much on airfare when they fly to a $2500 training (by the same speakers). You will argue, this is one day, the $2500 is 3 or 4 days. My thoughts there:  if you are coming to PDC, you are likely an accomplished software professional. Do you really need HOLs? All four day trainings have them.  I think a one day session is great because it forces the presenters to prioritize, to compress. Given the caliber of speakers we have, they are not going to cut you short, they are going to figure creative ways to deliver the message and insights that matter most. This is double value for you because the price is great, and we make the most of your time.


    More info?
    Official abstracts and bios for the speakers at the PDC pre-con website

    </marketing>

     

    <themeat>
    Now the inside story to the Pre-cons..

    The goals:
    There were three key tenets at the core of pre-con planning:

    1. I wanted it to be deep content, centered around guidance. The topics had to be interesting and contentious; when contentious was not a match (e.g. WPF or Silverlight), we went for speakers with huge experience that would be analytical and critical of the technology, folks with insightful experience both in the technology presented, the predecessor and competing technologies, and the challenges the technology addresses.
    2. Steve Cellini, the uber PDC owner, wanted top quality. On the very first meeting, he said "Quality is the goal! Get only the top speakers and make sure the delivery is exceptional" and when I explained to him that I needed to balance speakers due to budget he did not even blink at it, "blow the budget if you need to!"   I think you will see Steve's support both in the line-up of incredibly talented speakers and in the number of speakers; a lot of sessions have two or three presenters, I firmly believe this will make the sessions more entertaining, and drive the content/guidance to a more insightful level. The few sessions that have a single speaker, it is because we felt the delivery was better with that single speaker!
    3. Complimentary to PDC. This was Mike Swanson's role; we wanted no overlaps and we wanted synergies with PDC sessions.
      Avoiding overlap was not hard, pre-cons are focused on shipping technology and PDC sessions focus on futures; that said, on any topic covered in both pre-con and PDC, a pre-con should frame a technology, its challenges,  and the current best practices, so that when you attend a PDC session on the future of the technology, you can get the most out of that topic, and put the future solution into context with the challenges and today's solution.

      
    Selecting the sessions
    I started with ~50 topics. I was all over the map, XNA, HPC, WPF, WF, Sharepoint, Live, F#, LINQ, etc.  Then I mapped them to PDC tracks  (sorry, afaik I can't share these but I can say there were four), for pre-con we added an extra track called "industry/fun" track; which aimed at doing some thing different from what you expect at PDC. 
    We quickly narrowed it from 50 to 25 by applying a rigorous quality criteria:

    • Do we have enough content for a whole day?  Is a day enough to grasp the topic and actually learn?
    • Is this topic something commonly taught elsewhere?  If so, is it relevant to PDC content?  If not relevant to PDC and taught elsewhere with same quality of presenter, we skipped it.

    When I was down to 20-25 sessions, we shared them with other teams at Microsoft and with an "Advisory board"; the advisory board is mostly Regional Directors; all of them trainers/influentials and community leaders. It was great to hear what they thought the community needed; it was quite different from what I was expecting, but they provided great info to back up their arguments, so we listened!

    After the prioritization, we went after great presenters for each topic. If we did not find an absolute rock-star (inside or outside Microsoft ) we cut the topic.

    In the end, there were still a few painful cuts.  ASPX/MVC stuff, XNA, new MFC/Win32 stuff, and a few others.  There was a an important goal to achieve: variety! . Some people inside Microsoft didn't get that it did not matter not to have the 10 most popular, but we needed to have some thing for everyone!   I could agree that ASPX would have had more attendees than say "advanced debugging", but I needed to offer some thing to the C++ developers, and the web developers already had Silverlight, you get the drill. "Something for everyone" was maybe a secondary tenet.

    The sessions themselves and the dynamics: Why the session, why the speaker(s)?
    I aimed to add context to each session, without repeating the abstracts and speaker bios.   Please do read those before reading the ramblings below; my thoughts below are meant to add context on why the speaker or topic, but I did not repeat the outline or objectives for each session.

    • WPF ( by Charles Petzold).  Despite the hype for web apps; there is still a lot of software that can't run in the browser (due to security, performance, off-line requirements, preserving an investment, and many other reasons). WPF is Microsoft's latest and richest UI framework for writing desktop applications; XAML and its declarative model are at the core of any future presentation stacks at Microsoft. Easy to see why we needed to go deep and explain the fundatmentals of WPF, and who better to present it than Charles Petzold?  
      Charles has written half a shelf of Windows Programming books. Two WPF books already! He is funny, he is a brilliant writer and speaker, he is very thorough and he speaks likes he sees it.  Early in the cycle, I told Charles he could have unlimited access to the WPF architects -most of them were eager to work with Charles - but then Charles said in an email when discussing his abstract "if I could re-write my WPF book, I would start with ... " and there I knew it was time to leave him alone; he has clearly thought it through (end-to-end) many times.

    • Silverlight ( by Jeff Prosise)-- Silverlight is a subset of WPF that brings richness, and cross-platform .NET programmability to the web; clearly a disruptive technology. No one has more experience training web developers than Jeff Prosise.  He is very critical and tends to take a 'best practices' angle to his talks so I thought he would be most appropriate to introduce people to Silverlight. We could have had an MS person deliver this session, but it would have been too "blue". Jeff will bring the perfect balance of experience and insights for people to really understand Silverlight and know when and how to apply it.

    • Data ( by Mike Pizzo & Jose Blakeley) --  This session topic was selected before I found the speakers. Given how rich our data programmability APIs are, there are lots of people asking for advice on when and how to use each technology.  There are also people wondering if the one they are using will be deprecated, etc.  My guess is that I have read > 3 books, and dozens of whitepapers and even more blog posts on our data APIs and I still could not authoritatively explain when to use each technology (and why), what best prepares me for the future?, etc.  If you want the answers to those questions, you should come to this session and ask Mike & Jose!  These two guys have been around since OLE DB. They are both incredibly smart and know data inside out; I doubt there is any one better to answer those questions and set you straight on the best fit for you.

    • Debugging ( by Mario Hewardt and Daniel Pravat).  It is a PDC tradition to have a very deep win32 session; at first I was going to skip this tradition because I had only 10 sessions and felt that the "inside the Winxx kernel" had been done enough times; but then I went back to my win32 days and remembered that despite my getting good at COM and Win32, debugging was always a challenge that I never mastered. My guess is that there are others out there in this same situation; the sad part is you never know how much more effective you can be until someone shows you, that is why the session, we need the experts to show us that it is easy.  The challenge when I decided to pursue it as a session was to find the speaker for the topic.  I ordered three debugging books online; when I ordered "Advanced Windows Debugging" I did not know the authors, but it was highest ranked book (5 stars).  I read 1/3 of each book and it was a no-brainer that these folks were it!  Then I met them and was reaffirmed that they were perfect for a debugging session: They were cautious before agreeing to do it; they had a lot of questions, and then they built a plan, and have been executing since. They also make a really great team, complimenting each other very well. I have read the book and can guarantee it will save you time next time you want to debug a problem, join the session and also save time from reading the whole book! I am sure Mario & Daniel will share their best tips at the pre-con.  

    • Concurrent programming and parallelism ( by Stephen Toub, Joe Duffy & David Callahan).  This was a no-brainer; it is a trend in computing, it is still new and there is a lot of room for guidance towards best practices.  I have seen Stephen & Joe present and both of them are great; this is one of those talks where you will learn a lot and be better prepared for actual PDC sessions; we have been monitoring carefully to make sure there is no overlaps and all the sessions compliment each other well.

    • VSTS ( via Brian Randell).  This session was picked early because the topic is very real-world. Lots of people have bought VSTS but don't know how to use it to its potential; I have been there myself.  I went to the VSTS team and asked them to present it and they said "Brian Randell is the man for this".  
      I was surprised they recommended an external, but then I spoke to Brian it was obvious he is full of best practices and advise to avoid the worst practices.  He is perfect for this session.  After the session was announced, the VSTS team heard that the Agile session had a panel and they asked to have a panel too; Brian Harry, Sam Guckenheimer and others are coming for Q&A at the end of Brian's session. This detail might not be in the abstract.

    • Windows Mobile apps ( Doug Boling & Jim Wilson).  Another trend ready to boost. My guess is there is lots of people who have Windows and .NET skills that they can use on mobile, but that does not fully prepare them for mobile; you have to understand the constraints (CPU, battery,etc.) and the tools (debuggers, emulators,etc.) Doug and Jim are the two best known Windows mobile trainers. I am quite excited that we got both of them for a joint session; I know the content they are preparing is new, so any one who knows them or has seen them before, should still get a lot out of this session. This session should also compliment any other Mobile sessions at PDC.

    • Agile (Mary Poppendieck and Grigori Melnik).  Practical advise from the industry and from within Microsoft.
      Mary brings industry experience, best practices, and a lot of insights on going to agile and sustaining it.   Mary is going to deliver some invaluable advise to help you overcome the most common challenges and pitfalls. In the later part of the seminar, Grigori will share the Microsoft perspective: How our own Patterns & Practices team does it.  Agile is a huge deal for the p&p team.  I am excited to hear their advise. For those more 'experienced' agile practitioners, there is also a panel at the end.  Peter Provost and Jim Newkirk are joining Mary & Grigori to answer all questions!

    • WCF and REST (Juval Lowy and Ron Jacobs).  This session will be full of great advise and fun. Juval is a probably the most recognized WCF/SOA speaker outside of Microsoft; he wrote the book on it and has spoken at all major conferences on the topic; but this time we threw him a curve: Ron is going to come and talk about REST.  I am confident between the two of them we will get a good pros & cons on SOAP and REST,  how these two can co-exist in a WCF world,etc.   These two folks have great chemistry; I really want to see them as a team! I have seen Ron present this REST talk before, but I am sure with Juval in the room the level will be raised immensely.   

    • Performance in the .NET framework (Mark FriedMan, Joe Hellerstein & Vance Morrison). This session is also aiming to address a real-world scenario. .NET performance is good but with perf, there is always room for improvement; Vance has been working on .NET from the very beginning, and has been a huge part of the team that has made a lot of progress;  Mark & Joe joined later, but are pretty deep into areas like thread pooling and garbage collection. I can't wait to hear these folks share their advise, I am certain there will be enough to boost the perf in your app, and to do at least three "Aha!"s during the day..  From what I have seen these 3 folks work great together, I think the session will come together very cohesively.

     

    </themeat>

    Registering for pre-cons. 
    Now that you have seen the line-up; I hope you do consider joining.  It is going to be fun and enlightening. I promise!
    I have to close with an FAQ that has come up several times already: if you already registered for the conference and need to change your registration so you can attend the pre-con, it is possible to do it, just email PDC2008@ustechs.com and they will help you.

    Feedback/Suggestions: 
    If you have a suggestion for improving the pre-cons feel free to email me via the blog.  We welcome all suggestions!   

     

    That is it (for now)!   C U at PDC Pre-cons!

  • Jaime Rodriguez

    Client profile explained..

    • 10 Comments

    As I mentioned on the SP1 cheat sheet, client profile is an exciting new deployment feature in SP1..  
    Troy Martez has an intro paper and a deployment guide for it. 
    Those docs and his coming blog are the ultimate reference on client profile, but I wanted to share the whole context and my 2c on the subject [because I have seen a lot of questions on the feature]. 
    [For most of you readers half of this is old news, feel free to skip to the highlighted sentences].

    The motivation for client profile:

    The .NET run-time has gotten big over time.  The growth was positive- we got WPF, WCF, Card Space, LINQ, etc- but the trade-off was increased download size and increased install time .
    The bad rep on download size is compounded by how we package the off-line installers.  For example, the off-line 3.5 SP1 installer,  is ~230 MB. The reason for it is because we ship x86, x64, and ia64 bundled together. The reality is that if you used the 3.5 SP1 boot-strapper and installed online, you would get 1/3 of that size, with a ~3 MB bootstrapper (instead of the whoopy 200mb).   

    Introducing client profile

    The idea is simple:
    1) package the subset of the framework that is most commonly used by client apps.
    2) install that subset.
    3) later (on the background preferably), upgrade the subset installed to a full .NET 3.5 SP1. 
    This package in #1 above is the client profile SKU.  Client profile includes WPF, Windows Forms, WCF, the BCL, data access, etc.  (for a full manifest, check Justin's post).
    The net result is that client profile gives you a .NET run-time with an initial download of ~28 MB and install time much shorter than full .NET framework. 
     

    The details on the implementation
    If you read #1 above, client profile is a subset of the framework. The more accurate explanation is that it is a subset of .NET 1.1x + subset of 2.0 + subset of 3.x so unfortunately we can not install client profile on a machine that already has a .NET framework installed.  

    • Why only install on 'clean' machines?  If you have the full 2.0 framework, and we installed a subset of that, it that could break your 2.0 apps already installed.
    • If you think further into this, Vista shipped with the .NET framework 3.0 in the box, so that gets Vista out of the way and we conclude that client profile is supported on XP machines that do not have a framework installed at all.  For WS03, since it is server, we don't do client profile.
    • On any machine that is not XP or that already has a framework, when you try to install client profile, it will install the full .NET 3.5 SP1.  

    If you see above again, step #3 is upgrading the framework from client profile to full .NET 3.5 SP1.. how does it happen?

    • Once you install client profile, the next time Windows Update runs on that system, it will try to upgrade it to full .NET 3.5 SP1. This is nice because the download and install happens on the background (for me windows update runs at 3 am every day).
    • There is likely a brief period of time when a machine between client profile getting installed and Windows Update upgrading it to a full 3.5 SP1. What happens during this period?
      • Any apps coded against 3.5 SP1 client profile will run fine.
      • Any apps that need the full framework, will prompt for a full framework install when they are launched.  You will be able to install full-framework seamlessly you just won't get the benefit of this happening on the background (if you used Windows Update).

    The temporary gotcha
    .NET 3.5 SP1 shipped last week, and client profile is available for download but Windows Update does not start updating machines to .NET 3.5 SP1 until they complete their testing - 4 to 6 weeks from now, we hope-.   So if you installed client profile today you would not be upgraded automatically like we planned. Because of this reason, we are labeling the Client Profile release as "Preview" until Windows update begins upgrading systems to 3.5 SP1.

    This does not mean the run-time with change; the run-time is frozen. We have the preview out for people to start testing their app against client profile and planning the deployment;  we just recommend that you wait and release a client profile app only after Windows Update begins upgrading systems to 3.5 SP1.

    Other FAQs:
    A point of confusion is the packaging.  Client profile is ~28 MB, but if you go to download it, you will see two options available: 

    • The bootstrapper for client profile is a tiny exe ( < 300K). It should be used for applications that will be online when you install. The bootstrapper looks at your OS and hardware platform ( e.g. x86) and only downloads the needed bits (~28 MB). This is online scenario is what client profile is designed for.
    • The client profile off-line installer. Most people would think this is a 28 MB file, would not you? 
      Well, unfortunately not. It is actually ~250MB. The reason for that is we assume you will be off-line and your application can't fail at install time, so we include the whole 3.5 SP1 package plus the 28 MB client profile, this way if you try to install it on a machine that already has the framework, we can still install 3.5 and have your application will run. 
      • My personal 2c here is that most people who need to install off-line would be better off installing the full 3.5 SP1 framework at once. It is slightly smaller package and most importantly gets it all out of the way, so there is no WU upgrade later; the only gotcha is that the installer will take a bit longer to install than using client profile.

    I am sure there are a lot more questions you will have (like how do I create an app that targets client profile). 
    I will come back to client profile later, or at least point you to Troy's blog since he is working on explaining all of these.   For today, I just wanted to explain the platforms and scenarios that client profile aims to address, its relationship to Windows Update, and the explanation on the off-line installer's size (this was causing confusion, at least for me).  For the record a benefit I did not tout today is that client profile lets you customize the UI for the install experience; I will have to come back to that one since it is neat-o.

  • Jaime Rodriguez

    On WPF reference applications and the new location for the WPF Hands-on-lab for building the Outlook UI?

    • 8 Comments

    Tim is OOF and his automated response forwards WPF requests to me..   want to know the most FAQ was last week ?  Where is the hands-on-lab for building the Outlook UI using WPF?.. 

    Answer: It is here.    Give me a few days to look through it and ask Ronnie –the author – if we should post it on windowsclient.net too..  

    There was 6 requests for it last week,  which is great because it confirms some thing we are thinking today: we need more WPF reference applications.  

    We do have Family.Show,  but are thinking of a new one. Should we??

    If so, what is the scenario?   should it be a LOB or a consumer scenario? high-end graphics?    Do you really need step-by-step HOL?? Or would a slightly higher level write-up explaining all the trade-offs and best practices do??  [we are leaning for the latter]..

    Let me know via comments or email…

    Thanks!!  

     

    PS – if we move it or add it to windowsclient.net I will put it in the comments for this post to avoid an extra post…   I tried to do that on Tim’s original post but new comments were disabled..

  • Jaime Rodriguez

    cheat-sheet to some of the WPF 3.5 SP1 features..

    • 8 Comments

    .NET 3.5 SP1 buzz peaked very early at the beta.  At the time I was immersed in Silverlight, so I am now having to catch up; which is a bit of work since the release is packed with lots of new features.  Below is my cheat sheet to date; I tried to group them on what I saw were the "core" investments.

    The official release notes on 3.5 SP1 is at windowsclient.net/wpf.
    Tim Sneath has a  great post that puts the enhancements into context both on size ( # of changes) and on impact ( based on customer feedback ) .

    Deployment

    Performance:

    Graphics:

    • Adam Kinney interviewed David Teitlebaum around beta1 time-frame about the graphics improvements: hardware accelerated bitmap effects, D3DImage, WriteableBitmap, etc.
    • Greg Schecter has this great series on hardware accelerated bitmap effects.
    • Dr. WPF's tutorial on D3DImage is very comprehensive.  This is a niche feature but it does enable a lot of scenarios where the previous solution [with airspace] was not ideal.   BTW, happy blog-anniversary Dr. WPF!

    AppModel:

    • Adam Kinney has a great interview with Jennifer Lee.   I must say I am a bit surprised there is not more out there XBAPs.  XBAP got a bad reputation at 3.0 launch because it did not work on Firefox, and at the time WCF required Full trust and XBAPs did not elevate. All of that has been fixed now, so I am excited about the improvements they did for XBAP in 3.5 SP1 (like the HTML splashscreen).
    • Lester's has a sample too on WebBrowser control [this is a very handy feature, compared to frame].

    Tools/Other:

    Data:

    The list above is not all comprehensive, but it can help you catch up.  Please let me know what I missed [I am sure there is lots of that]...

  • Jaime Rodriguez

    Datagrid (part3): styling.

    • 6 Comments

    In this third and final part of the datagrid series ( part1, part 2) we get into styling the datagrid a little bit. 

    This part is not an all comprehensive tutorial on styling datagrids, I will just touch on what we did for my sample and share a few tips & tricks.

    Here is the final look. 

    datagridFinal

    Here is the declaration for the whole data grid.

    <dg:DataGrid ItemsSource="{Binding Data}" Margin="20"                  
    AlternationCount="2"
    RowStyle="{StaticResource RowStyle}"
    AutoGenerateColumns="true"
    Grid.RowSpan="1" x:Name="BigKahuna">


    If you see above, I templated the Header. All I wanted was a blue background with white foreground.

    <Style x:Key="ColumnHeaderStyle" TargetType="{x:Type dg:DataGridColumnHeader}" 
    BasedOn="{StaticResource {x:Type dg:DataGridColumnHeader}}">
    <
    Setter Property="Background" Value="{StaticResource DataGrid_Style0_Header}" />
    <
    Setter Property="Foreground" Value="White" />
    <
    Setter Property="HorizontalContentAlignment" Value="Center" />
    </
    Style>
    I also wanted Alternating rows, so I set AlternateCount to 2 in the datagrid and then I created a trigger for the RowStyle.
    <Style x:Key="RowStyle" TargetType="dg:DataGridRow" >
    <
    Style.Triggers>
    <
    Trigger Property="AlternationIndex" Value="1" >
    <
    Setter Property="Background" Value="{StaticResource DataGrid_Style0_Alt1}" />
    </
    Trigger>
    <
    Trigger Property="AlternationIndex" Value="0" >
    <
    Setter Property="Background" Value="{StaticResource DataGrid_Style0_Alt0}" />
    </
    Trigger>
    </
    Style.Triggers>
    </
    Style>

    One customization that I did not do in the demo, but is probably common is tweaking the selection. By default DataGrid does a blue highlight, imagine you want to change that color to a green; you would just need to override the Template for DataCell.

    <Style x:Key="CellStyle" TargetType="{x:Type dg:DataGridCell}">
    <
    Style.Triggers>
    <
    Trigger Property="IsSelected" Value="True">
    <
    Setter Property="Background" Value="#FF3FC642" />
    </
    Trigger>
    </
    Style.Triggers>
    </
    Style>
    and of course apply this on the datagrid CellStyle='{StaticResource CellStyle}'
    Voila!
    datagridhighlight 
    In the usual WPF way, styles and templates allow incredible flexibility and leave the designer in control for a visually stunning look with no code.
    The rest is tips & tricks for designers. 

    If you look in the obvious place ( Edit Template) Blend does not have a lot of design-time support for all the pieces in the datagrid because the parts to customize are not quite parts of the ControlTemplate, but for the most part a few of these are DataTemplates, so you can workaround by creating any ContentControl, and editing the ContentTemplate there.

    To edit the parts of the DataGrid's controlTemplate, you can actually drop and individual parts (like DataGridHeader) of the template in a regular window and edit their style there. 

    Blend

    The only 'tricky' one you might run into is DataGridHeaderBorder (because it does not expose a template). My advise there is to go ahead and select Edit Style -> Create Empty.  Treat it as you would a border.  
    Window4.xaml in the sample code has a small example of editing the pieces. [it is not complete by any means. It is also not pretty].

    That is it in terms of getting my little portfolio data styled and it closes the DataGrid series. I hope it is useful to some one reading it.  It was fun playing with the DataGrid. You don't realize how big this thing is until you play with it and see all the small, yet meaningful options it has.

    For feedback, best place is the codeplex discussion
    This build is a CTP, but it is quite functional and near completion. The control will ship out of band so don't wait too long; it will be shipping soon.

  • Jaime Rodriguez

    datagrid (part 2) -- Show me some code.

    • 7 Comments

    In part 1, I walked through some of the features in datagrid.
    The source for the series is here.

    In this part, we will create a UI that looks like this:
    datagridFinal 

    I will mostly highlight the interesting parts [instead of going on a step by step].
    The source is available and it would be repetitive if I go step-by-step. 
    One thing to note is that (approximately) 90% of the work to customize it is in XAML.  Some of it I did in code just to illustrate a point.

    DataGridTextColumn bindings were the simplest ones. 
    You can assign a DataFieldBinding -- which is an actual Binding to the data you want. I liked the approach of passing the full binding [instead of a property name] because it allowed me to pass parameters like StringFormat (see below) and converters and other similar binding features.  Nice!

     
    <dg:DataGridTextColumnDataFieldBinding="{BindingDescription}"Header="Description"/> 
        
    <
    dg:DataGridTextColumnDataFieldBinding="{BindingQuantity}"Header="Quantity" />
    <
    dg:DataGridTextColumnDataFieldBinding="{BindingQuote,StringFormat={}{0:C}}"Header="Quote" />  
    From above, notice I mostly passed strings into the header property.  This was my choice; I could have more complex objects since Headers are Content controls and have a HeaderTemplate, but I did not need it here.  


    The symbol column  is a DataGridHyperlinkColumn; I did nothing to customize it. If you compare it to DataGridTextColumn you will see an extra property. On the DataGridHyperlinkColumn,  DataFieldBinding -- looks or expects a Uri.  and the ContentBinding looks for the text that the UI will display.

     

    <dg:DataGridHyperlinkColumn DataFieldBinding="{Binding SymbolUri}"  
    ContentBinding="{Binding Symbol}" Header="Symbol" SortMemberPath="Symbol"/>



    DataFieldBinding  - is where the data (Uri) is coming from.  
    ContentBinding - is the 'text' that is displayed on the hyperlink. 
    SortMemberPath - is the data used for sorting. The datagrid will look at the property this path points to and if it implements IComparer will automatically handle the sorting. [In this app, most of the columns sort and I implemented no sorting logic at all :)]  

    If you run the app, you can also see the "edit' behavior for DataGridHyperlinkColumn. You can edit the Uri, but not change the actual text (ContentBinding). You can manipulate it programmatically, but not from the editing experience.


    Today's change column
    I implemented as a DataGridTemplateColumn.

    <dg:DataGridTemplateColumn CellTemplate="{StaticResource DailyPerformance}" 
    Header="Today's Change" SortMemberPath="DailyDifference" />

    A DatagridTemplateColumn is one where I can apply a CellTemplate so that it generates the UI.  I first chose it for this column because I wanted to implement the behavior of highlighting gains ( >0 ) with Green and losses ( <0) as Red using a  DataTemplate.Trigger, but that did not work so I ended up using a Converter. Hind-sight this is likely a better solution [more performant] any way.

    <DataTemplate x:Key="DailyPerformance">
    <TextBlock   Text="{Binding DailyDifference, StringFormat={}{0:C}}" 
    Foreground="{Binding '', Converter={StaticResource StockToBrushConverter},
    ConverterParameter=IsDailyPositive }"> </TextBlock> </DataTemplate>

    Notice that I was still able to use a SortMemberPath on the DataGridTemplateColumn. This is really nice because regardless of what my UI looks like I can still sort the data.Total Gain column uses the same technique than Today's change.  


    Rating column is a little gaudy on purpose. 

    <dg:DataGridTemplateColumn 
    CellTemplateSelector="{StaticResource StarsTemplateSelector}"
    Header="Rating" SortMemberPath="Rating"/>

    Here I used a TemplateSelector just for illustration purposes.

    The selector is trivial. All it does is look for a template in a resource dictionary for the datagrid.

    public class StarsTemplateSelector : DataTemplateSelector 
       {
           public override System.Windows.DataTemplate 
               SelectTemplate(object item, 
               System.Windows.DependencyObject container)
           {
               StockXAction sac = item as StockXAction;
               FrameworkElement  fe = container as FrameworkElement; 
    
               if (sac != null && fe != null )
               {
    
                   string s = sac.Stars.ToString() + "StarsTemplate";
                   DataTemplate ret =  fe.FindResource(s) as DataTemplate;
                   
                   return ret; 
                    
               } 
               return base.SelectTemplate(item, container);
           }
       }


    From the XAML, you can also notice the SortMemberPath again. The UI now has Star ratings on it, yet I can still sort and did not have to write any code !!

    Separator Columns are empty 'dummy' columns I added just make empty space to separate the colums from autogenerated ones. See Autogenerated Columns below for why.

    Autogenerated columns
    I wanted to leave AutoGenerateColumns="true" so you could see how the 'raw' data turns into the view.  It is also nice because you get to see some of the Column types I did not use for example the ComboBoxColum -- you can see it on the Autogenerated rating column. It is an enum, and it turns into a ComboBoxColumn.

    Default data for new rows
    If you scroll to the bottom and a new row [functionality that comes out of box]. You will see this:

    datagridNan

    The NaN is a problem. What happens is here is it is trying to calculate Gain, but data has not been initialized.

    The workaround is to handle the DataGrid's InitializeNewItem. This will be called as a new record is initalized.

    this.BigKahuna.InitializingNewItem += 
    new InitializingNewItemEventHandler(BigKahuna_InitializingNewItem);


    void 
    BigKahuna_InitializingNewItem(objectsender,

    InitializingNewItemEventArgs e)
            {
                //cast e.NewItem to our type 
                StockXAction sa = e.NewItem as StockXAction;
                if (sa != null)
                {
                    //initialize 
                    sa.Symbol = "New data"; 
                    sa.Quantity = 0;
                    sa.Quote = 0; 
                    sa.PurchasePrice = 0.0001; 
                } 
            }


    Copying data on DataGridTemplateColumns

    Another issue you would notice is that if you do a Copy (Ctrl-C) or right click into Context menu which I added, the TemplatedColumns are not copied by default.  What I needed to handle in order for copying to work is to pass a binding to ClipboardContentBinding.  So we can tweak the template we had earlier and I will be tricky and pass the enumerator (Stars).

    <dg:DataGridTemplateColumn CellTemplateSelector="{StaticResource StarsTemplateSelector}" 
    Header="Rating" SortMemberPath="Rating" ClipboardContentBinding="{Binding Stars}" />

    Now when I copy paste, I do get the value generated from ToString() on the enumerator.

    One more thing to mention around Copying is that Data*Column has a CopyingCellClipboardContent event. This is good for overriding the value if I did not have a binding; what I noticed on this build is that if there is no binding set on ClipboardContentBinding, the event is not firing.  This will be fixed by RTM, interim just pass any binding (like {Binding}) and when the event fires you can override the value that will be cut & pasted from code.

    OK, that covers most of the functionality. In part 3 we can take care of the styling.

  • Jaime Rodriguez

    dabbling around the new WPF datagrid (part 1)

    • 10 Comments

    On Monday, the WPF team released the CTP of their new datagrid control.  
    You can download it from here.  [Note that it requires .NET 3.5 SP1, released monday too]

    I have been playing with it so I created this 3 part series.

    • Part 1 (this write-up) is about the features in the grid and the ones missing from it.
    • Part 2 is a hands-on exercise to apply the features to customize the presentation of data (aka view) of the datagrid.
    • Part 3 includes a few tips & tricks on customizing/styling the datagrid.

    The source for this sample is here.

    Getting Started  was trivial. 

    1. I got the bits from codeplex,
    2. created a new WPF application, and
    3. added a reference to the WPFToolkit.dll.
    4. From my Window1.xaml, I added the xmlns declaration so I could refer to the datagrid. No need to map the assembly, the tools do that for you.

    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
        Title="Window1" Height="300" Width="300"    
        >

    I had some 'dummy' data simulating financial transactions so I took advantage of AutoGenerateColumns feature in the grid to get a quick 'fix':

    DataGrid0

    The results were quite rewarding for a line of code. I could Reorder the columns, Resize the Columns, Sort by Column, Add New Rows , Edit the data, Select Rows ,  and Copy to Clipboard.

    I then moved on quickly to styling it a little bit..  Like every thing else WPF, the datagrid is incredibly flexible on customization by using styles and templates. 
    In a few minutes, I hand-wrote this

    <Window.Resources>
            <SolidColorBrush x:Key="DataGrid_Style0_Header" Color="#FF4F81BD"/>
            <SolidColorBrush x:Key="DataGrid_Style0_Alt0" Color="#FFD0D8E8"/>
            <SolidColorBrush x:Key="DataGrid_Style0_Alt1" Color="#FFE9EDF4"/>
            
            <Style x:Key="ColumnHeaderStyle" TargetType="{x:Type dg:DataGridColumnHeader}">
                <Setter Property="Background" Value="{StaticResource DataGrid_Style0_Header}" />
                <Setter Property="Foreground" Value="White" />        
            </Style>
            <Style x:Key="RowStyle" TargetType="dg:DataGridRow" >
                <Style.Triggers>
                    <Trigger Property="AlternationIndex" Value="1" >
                        <Setter Property="Background" Value="{StaticResource DataGrid_Style0_Alt1}" />
                    </Trigger>
                    <Trigger Property="AlternationIndex" Value="0" >
                        <Setter Property="Background" Value="{StaticResource DataGrid_Style0_Alt0}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
    
        </Window.Resources>

    and got this:

    DataGrid1

    [We will cover styling in part3, let's first walk through all features]: 

    Selection Unit: 
    Under the hood with the grid, you are really selecting cells, but the grid has a couple nice modes to make it easier for developer to use the concept of selected rows:

    • Cell - selects cells.  In this mode, SelectedCells property has selected cells and SelectedItems is null.
    • FullRow-- when a user selects a cell in a row, all of the cells in that row are selected. In this mode SelectedCells has all the selected cells in that row. SelectedItems has the selected rows.
    • CellOrRowHeader - a mix from the two above, where full-row select happens when clicking on the RowHeader (if its showing).  In this mode:

        o SelectedCells has all the selected cells, including all the cells in a selected row when a row is selected through the RowHeader

        o SelectedItems has the rows which are selected through the RowHeader, or is empty if only cells are selected (i.e., highlighting all the cells in a row will not add that row to SelectedItems)

    Selection Mode:
    In Single mode, I can choose a single unit (see above for unit) and in Extended Mode I can select multiple units. 
    The usual keyboard navigation short-cuts apply (Shift takes you to the end of current row, Ctrl preserves previous selection, etc.)

    GridLines

    Using GridLinesVisibility property, I can choose which gridlines are visible:  All, Horizontal, Vertical, and None.
    I can also choose the color for the horizontal and vertical gridlines.

    Headers (Row & Columns)

    By tweaking the HeaderVisibility property, I can choose which headers are visible:  All, Column, Row, None.  
    The headers for each column can be customized/styled using a HeaderTemplate. 

    Column operations

    Autogeneration of columns works quite well.  The default mappings are:

    Data Type Generated Column
    string DataGridTextColumn
    Uri DataGridHyperlinkColumn
    bool DataGridCheckBoxColumn
    enum DataGridComboBoxColumn*

    *the ComboBoxColumn is created only if the field is writeable ( which happens when the property is not read only).
    For other types (e.g. DateTime or objects) the DataGridTextColumn will be the default with a ToString() on the object.

    You can customize AutoGeneration of columns by handling the AutoGeneratingColumn event. You will see this in part2.

    ReadOnly columns  is missing from the CTP, but that is not a huge problem, you can easily accomplish ReadOnly behavior by using DataGridTemplateColumns and replacing the templates with read-only controls ( like TextBlocks).

    Column Resizing and Reordering is implemented out of the box and is toggled on/off via the CanUserReorderColumns and CanUserResizeColumns  respectively. 
    If you want to control reorder per column, there is a CanUserReorder property on the column itself.

    Frozen columns. A frozen column is one that does not scroll out of view when the user scrolls in the horizontal direction. When a column is frozen every column displayed to its left are also frozen.  Frozen columns is supported out of the box. You can control it by setting the IsFrozen property on a column.

    You can see frozen columns in the demo I created by right clicking and showing the ContextMenu.

    Row operations

    Adding new rows is supported. You can enable it via CanUserAddRows. Deleting rows is supported too, controlled via CanUserDeleteRows.

    For alternating rows, the datagrid has an AlternationCount property for controlling AlternateRows. 
    The way it works is you set AlternationCount to the total number of styles/colors to be used. Usually this is two colors, truly alternating, but it could be more colors if needed [and you like to get funky]  

    Once AlternationCount has been set, on your RowStyle you can create a trigger that checks AlternationIndex (which should be 0 to AlternationCount-1) and set the style there. 


    Editing Cells

    Before getting into editing, I have to comment on entering Edit Mode.
    The Datagrid requires you to have focus in the cell in order to get into edit mode.  To get focus, you can click on a cell, or tab into it.
    Once you have focus, the most common gestures to get into edit mode are supported:

    • Using the Keyboard – cell has focus, start typing, goes into edit
    • Using the Keyboard – cell has focus, enter edit mode command (ex. F2), goes into edit
    • Using the Mouse – cell has focus, click, goes into edit
    • Using the Mouse – cell may or may not have focus, double click goes into edit.

    For programmatically manipulating the cell with focus or during edit mode, the datagrid has a property of CurrentCell and each DataGridCell instance has an IsEditing property

    You can customize the Editing experience for any column by providing a CellEditingTemplate.  [If you used one of the stock columns listed above, those automatically provide a template].

    Editing a cell has three commands that are fired as you get in and out of edit mode:

    • BeginEditCommand (any of the gestures above)
    • CancelEditCommand  ( press Esc )
    • CommitEditCommand  (press Enter, Tab to next cell, or change focus using mouse)

    Other features
    Copy to Clipboard
    is implemented.  Ctrl-C works fine. The data format appears to be tab delimited. Which is nice as it works seamlessly with excel.
    Keyboard Navigation [by using arrows and tab] works out of the box. 

    Some missing features already announced: 
    The big one is RowDetails.   I hear it is already in later builds, so the expectation is that it will be in by RTM.
    ReadOnly columns, and support for hidden columns. [Though I am thinking for those there is workarounds today].

    Bugs along the way and known issues.

    The only one I ran into is that DataTemplate.Triggers is not working on this build.  I hear it will be working on later builds.

    Show me the code (or demo).
    Playing with all the features above is easy. 
    The sample app I Created has a little bit of UI data bound to the datagrid that lets you manipulate the grid to see most of the features above. 

    In Part2, we start using these features to build a more 'insightful' view of the data.

Page 1 of 1 (7 items)