BASTA! Spring 2010 – Model-View-ViewModel
February 24th, 2010Hallo liebe Freunde der BASTA!, VB.NET'ler und Teilnehmer an meiner Session zum Model-View-ViewModel-Pattern. Folgend die versprochenen Slides und die Beispielanwendung zum Download.
Viel Spass damit,
Thomas
From Visual Studio 2010 Release Candidate back to Beta 2
February 22nd, 2010If you’ve played around with Visual Studio 2010 Release Candidate (RC), you sure have noticed that it’s pretty fast. E.g. the WPF- and Silverlight-Designers come up quickly and much faster that in Visual Studio 2008.
But for now there are some reasons to wait before installing Visual Studio 2010 RC:
- Silverlight 4 Beta is not supported. Silverlight 4 will be supported with the next public drop of Silverlight 4, what means when the Silverlight 4 RC is available. A date for that hasn’t been specified yet by Microsoft.
- The available Preview Version for .NET 4.0 of Expression Blend doesn’t work with Visual Studio 2010 RC. It only works with Beta 2 of Visual Studio 2010. A new version will be available soon as the Expression Website says, but no one knows what "soon" means.
The second point I just noticed now. And so I decided to go back to Beta 2 cause I’ve a session about Model-View-ViewModel this week at BASTA! Spring in Darmstadt.
To go back to Beta 2, make sure you uninstall everything of the Release Candidate. After I’ve uninstalled Visual Studio 2010 RC, I had additionally to remove .NET Framework 4.0 from Programs in Control Panel. Tip: Order the installed programs by date, then you see what you’ve to uninstall pretty good.
After I’ve installed the Beta 2 again, everything worked fine. But I got an error when compiling my WPF-project telling me the following:
"GenerateResource" task failed unexpectedly. System.DllNotFoundException: Unable to load DLL ‘FileTracker.dll’ …”
After some search I found a connect-entry on microsoft.com with the solution. My folder "C:\Windows\Microsoft.NET\Framework” contained a “v4.0” directory additionally to the "v4.0.21006" directory installed with Visual Studio 2010 Beta 2. After deleting the additional folder that has a higher number than v4.0.21006 (it’s the RC ;-)), the Beta 2 works fine again and I can compile everything as expected. Find the connect-entry that pointed me to the solution here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=501894&wa=wsignin1.0
Be careful with Default-Values of Dependency-Properties if you’re using Reference-Types.
February 11th, 2010I’ve justed finished a small PieMenu for a WPF-Application for one of our customers in switzerland. The PieMenu is displayed below with a black-red-style. The Style, colors and items can be changed individually. The colors and icons etc. in the PieMenu below are just the ones I’ve created for testing purposes.
While developing this PieMenu I’ve implemented several Dependency-Properties. Some of them containing ObservableCollections as Default-Values like this:
static PieMenu() { LeftSubItemsProperty = DependencyProperty.Register( "LeftSubItems", typeof (ObservableCollection<PieMenuItem>), typeof (PieMenu), new UIPropertyMetadata( new ObservableCollection<PieMenuItem>())); … }
I developed, made some UI-Tests, developed, made some UI-Tests and so on and everything was fine. But only till I’ve placed a second PieMenu in my Test-App. All Items of PieMenu1 and PieMenu2 were contained in PieMenu1 and PieMenu2. If you see the line above you can image what happened, if you sit in front of your code with at least 1000 lines of code in the PieMenu-class, you have to search a bit.
In the line above the ObservableCollection created as a Default-Value for the Dependency-Property is of course a static one, because the Dependency-Property is stored in a static variable and as you see in the code-snippet above it is initialized in the static constructor of the PieMenu-class. There’s no instance around at this point.
In other words that means every PieMenu that won’t explicitly specify an ObservableCollection gets the Default-Value, and that’s a static one that will be shared over all PieMenus in your app. So all the Items of every PieMenu are in every PieMenu. Isn’t that amazing?
The solution I’ve used is straight forward. Just create the Dependency-Property with a null-reference as its default-value:
static PieMenu() { LeftItemProperty = DependencyProperty.Register( "LeftItem", typeof (PieMenuItem), typeof (PieMenu), new UIPropertyMetadata(null)); }
In the Instance-Constructor assign a new ObservableCollection to the Dependency-Property and you’re fine.
public PieMenu() { LeftSubItems = new ObservableCollection<PieMenuItem>(); … }
Keep in mind that setting a local value in the Constructor won’t let you set this value in a Style anymore. But for the PieMenu and the ObservableCollection that won’t matter. You’re just adding and removing elements, you don’t want to define this Collection in a Style.
So, as you see in this post, you’ve to implement Dependency-Properties with Default-Values that are reference-types with caution.
Happy coding!
Visual Studio 2010 RC and Silverlight 4 Beta
February 9th, 2010Yesterday Visual Studio 2010 RC was released to MSDN Subscribers (find the link here), tomorrow it’s available for download for everyone. The performance is great as far as I can say by using it for at least one day. But it lacks on support for Silverlight 4 Beta.
If you’re developing Silverlight 4 applications, it is recommended that you stay on Visual Studio 2010 Beta 2 until new bits of Silverlight come out. “New bits of Silverlight” means a Silverlight Release Candidate. It is expected also for this month. Wow, how the time is ticking away. I just thought it has been some days ago since I read Dr. Tim Sneaths post about the Silverlight 1.0 RC, and now we’ll have the 4.0 Release Candidate soon.
The more I work with Silverlight 4.0, the more I love this Plugin. While I missed some things like e.g. implicit Styles and basedOn Styles in version 2.0, version 4.0 now contains both of them. Also printing is supported, WebCam- and Microphone-Access, Com-Interop for Out-Of-Browser apps etc. And the most important aspects for Business-Apps, Data-Access, Validation etc. are easy to do. With WCF RIA Services (formerly .NET RIA Services) you’ve a great framework for building Business apps. Also I’ve to say that I’m a total fan of the REST-based WCF Data Services (formerly ADO.NET Data Services), which are now also included in Sharepoint 2010. Silverlight contains a small Client API for accessing those services and make the classical CRUD-operations.
Silverlight 4.0 contains many great features to build really powerful apps. But not yet with Visual Studio 2010 RC. As soon as the new Silverlight-bits will be available, you’ll read it here.
Visual Studio 2010 Release Candidate (RC) available next week
February 6th, 2010The launch date for Visual Studio 2010 RTM is the 12th of April. This month there’ll be a Release Candidate (RC) and Scott Guthrie mentioned on his blog in a post about ASP.NET MVC 2 RC that it will be available soon. Now everybody speculates about the date and what “soon” means. Days or weeks?
The Blog about the Visual Studio quality tools contains the answer. Visual Studio 2010 RC will be released in the week of 8th February. Find the post with that information here:
Speaking at BASTA! Spring about WPF 4.0 and MVVM
January 24th, 2010The BASTA! (=Basic Days => in German Basis Tage) is “the” Conference in Germany about .NET. The BASTA! Spring is from 22nd to 26th February.
I’ve two sessions there: one Wednesday (24. February) and one on Thursday (25th February). I’ll talk about the new features in WPF 4.0 and about the Model-View-ViewModel-Pattern (MVVM). Find more (German) infos about my sessions on http://www.thomasclaudiushuber.com/talks.php. Also look at the conference-homepage www.basta.net, there are many great sessions. Looking forward to see you there and talking with you about Windows Presentation Foundation, Silverlight and your upcoming projects.
The DataGrid and the “Input string is not in a correct format” message in Silverlight
December 20th, 2009If you play around with the DataGrid in Silverlight and try some scenarios, maybe you come around the FormatException with the Message “Input String is not in a correct format”. You get this Exception if your Data-Object e.g. has a Property of type int and the user enters some characters in the DataGrid. The Exception doesn’t come up, instead the DataGrid shows it as a validation error. Let’s look at an example. Image you’ve a very simple Person-class containing a FirstName-Property of type string and an Age-Property of type int:
public class Person : INotifyPropertyChanged { private int? _age; private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value; Changed("FirstName"); } } public int? Age { get { return _age; } set { _age = value; Changed("Age"); } } private void Changed(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; }
Now let’s fill up a List with some Test-Persons and add that list to the DataContext of your page:
public MainPage() { InitializeComponent(); this.DataContext = new List<Person> { new Person{ FirstName="Thomas",Age=29}, new Person{ FirstName="Julia",Age=27}, new Person{ FirstName="Ben",Age=1}, }; }
No in the XAML-File of your MainPage a DataGrid could be defined like below. Notice the ItemsSource-Property that is bound to the DataContext:
<my:DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> <my:DataGrid.Columns> <my:DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}"/> <my:DataGridTextColumn Header="Age" Binding="{Binding Age}"/> </my:DataGrid.Columns> </my:DataGrid>
When the User now enters a string as Age, the FormatException is raised before the Property is updated and the Message of the FormatException is displayed in the DataGrid:
Now the question is, where to change this string. The DataGrid has a BindingValidationError-Event, but there you have only read access to the FormatException and the Errormessage. In the Property itself you can’t do anything, because the Exception is thrown before the Age-Property is set.
The solution is to define a Property special for Display in the Person-class. Normally you would create a ViewModel that encapsulates the Person-class and contains the additional property. In my case I implement the Property directly in the Person-class. I call it AgeDisplay-Property. Inside that property you can then throw your own FormatException with your special text. My Person-class now looks like this:
public class Person : INotifyPropertyChanged { private int? _age; private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value; Changed("FirstName"); } } public int? Age { get { return _age; } set { _age = value; Changed("Age"); Changed("AgeDisplay"); } } public string AgeDisplay { get { return Age.ToString(); ; } set { if (value == null) { Age = null; return; } int result; if (int.TryParse(value, out result)) { Age = result; } else { throw new FormatException("Age must be a number. " + " Characters are not allowed."); } } } private void Changed(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; }
No you simple bind the DataGrid’s Column to AgeDisplay instead of Age:
<my:DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> <my:DataGrid.Columns> <my:DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}"/> <my:DataGridTextColumn Header="Age" Binding="{Binding AgeDisplay}"/> </my:DataGrid.Columns> </my:DataGrid>
When the user now enters a string into the Age-Column, the text of the FormatException thrown in the AgeDisplay-Property is displayed:
Great news for Silverlight on Linux
December 19th, 2009The Silverlight-Plugin runs per default on Windows and MacOs. For Linux-Machines there’s an opensource implementation driven by Microsoft and Novell called Moonlight.
While Silverlight is currently in Version 3 available and Version 4 (already in beta) is expected for spring next year, the Moonlight implementation was only availabe in Version 1. And Version 1 means no C#, no CLR, just hacking JavaScript and XAML. But two days ago the big step for Silverlight on Linux was done and Moonlight reached version 2. It’s available for download: http://www.mono-project.com/Moonlight
I think with reaching that level from “only-JavaScript” to the managed C#-API, the future releases of Moonlight will be more closely to the Silverlight-releases for Windows.
Silverlight 4 – How to focus a TextBox that is contained in your Custom Control on Startup
December 17th, 2009Focusing a TextBox that’s inside a Custom Control isn’t so easy at startup of your application. Let me explain the problem that is also discussed on http://forums.silverlight.net/forums/t/151235.aspx. Imagine you’ve created a custom control that has a TextBox as Part-element. The Style that sets the Template would look like this:
<Style TargetType="local:SimpleControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:SimpleControl"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBox x:Name="PART_Text" Margin="10"></TextBox> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
You get the TextBox from the Template in the OnApplyTemplate-Method
public override void OnApplyTemplate() { base.OnApplyTemplate(); _partTextBox = this.GetTemplateChild("PART_Text") as TextBox; }
Now imaginge you want to focus your SimpleControl in the constructor of your MainPage like below:
public MainPage() { InitializeComponent(); HtmlPage.Plugin.Focus(); yourControl.Focus(); }
The Problem that occurs is that the OnApplyTemplate-Method is called after the Focus-Method. So you don’t have the TextBox defined in your Template. The Solution is very easy. Just hide the Focus-Method from the base-class and set a flag. But keep in mind that this won’t work if you store your SimpleControl in a variable of type Control, cause then no polymorphic call is made to the Focus-Method defined in SimpleControl. Here a sample implementation:
public class SimpleControl : Control { private bool _applyFocusToPartTextBox; private TextBox _partTextBox; public SimpleControl() { this.DefaultStyleKey = typeof(SimpleControl); } public override void OnApplyTemplate() { base.OnApplyTemplate(); _partTextBox = this.GetTemplateChild("PART_Text") as TextBox; if (_partTextBox != null) { if (_applyFocusToPartTextBox) _partTextBox.Focus(); } _applyFocusToPartTextBox = false; } public new bool Focus() { if (_partTextBox == null) { _applyFocusToPartTextBox = true; return true; } return base.Focus(); } }


