It’s a public holiday in the UK and the weather’s turned sour but playing with XAML and WPF can still bring on a smile – I’m not claiming it’s anything new or clever but I enjoyed it ( paste into Kaxaml or XamlPad to view );
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:ctl="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
xmlns:env="clr-namespace:System.Diagnostics;assembly=System"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="styleFontFamily" TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Calibri"/>
</Style>
<Style x:Key="styleTitleFont" BasedOn="{StaticResource styleFontFamily}" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="24"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style x:Key="styleProgressBar" TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground" Value="#FF0C4B5E"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="MinWidth" Value="192"/>
<Setter Property="Margin" Value="0,2,2,2"/>
</Style>
<Style x:Key="styleSubGrid" TargetType="{x:Type Grid}">
<Setter Property="Margin" Value="24,0,0,2"/>
</Style>
<Style x:Key="styleSubFont" BasedOn="{StaticResource styleFontFamily}" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Margin" Value="0,0,5,0"/>
</Style>
</Page.Resources>
<Grid>
<Grid.Resources>
<ObjectDataProvider x:Key="myDataSource" MethodName="GetProcesses" ObjectType="{x:Type env:Process}"/>
</Grid.Resources>
<ListBox
HorizontalContentAlignment="Stretch"
DataContext="{StaticResource myDataSource}"
ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Margin="0,2,0,4" BorderBrush="#FFCBCBCB" BorderThickness="1,1,3,3" CornerRadius="3,3,3,3">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF00DA09" Offset="0"/>
<GradientStop Color="#FF0A7606" Offset="1"/>
<GradientStop Color="#FF8DF57B" Offset="0.467"/>
</LinearGradientBrush>
</Border.Background>
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<StackPanel Width="Auto" Height="Auto" Grid.IsSharedSizeScope="True">
<TextBlock Style="{StaticResource styleTitleFont}" Text="{Binding ProcessName,StringFormat=Process {0}}"/>
<Grid Style="{StaticResource styleSubGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Col1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource styleSubFont}" Text="Process Id"/>
<TextBlock Style="{StaticResource styleSubFont}" Margin="0" Grid.Column="1" Text="{Binding Id}"/>
</Grid>
<Grid Style="{StaticResource styleSubGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Col1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource styleSubFont}" Text="Thread Count"/>
<ProgressBar Style="{StaticResource styleProgressBar}" Value="{Binding Path=Threads.Count, Mode=OneWay}" Grid.Column="1" />
</Grid>
<Grid Style="{StaticResource styleSubGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Col1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource styleSubFont}" Text="Total CPU Usage (seconds)"/>
<ProgressBar Style="{StaticResource styleProgressBar}" Grid.Column="1" Maximum="600" Value="{Binding Path=TotalProcessorTime.Seconds, Mode=OneWay}"/>
</Grid>
<Grid Style="{StaticResource styleSubGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Col1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource styleSubFont}" Text="Virtual Memory Size"/>
<ProgressBar Style="{StaticResource styleProgressBar}" Grid.Column="1" Value="{Binding Path=VirtualMemorySize64, Mode=OneWay}" Maximum="314572800"/>
</Grid>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Page>
it ends up producing a process list something like this;
and the UI is a bit horrible but I was just building an example of binding and found the whole “code-free” nature of that particular lump of XAML to be a very positive thing.
The other thing that made me smile today was thinking about how I can use Windows XP mode in Windows 7 in order to run up IE6 on an operating system that doesn’t have any .NET Framework installed and then I can show how the .NET Client Profile installation works.
That is, I spring up a virtualised IE6 on my Windows 7 desktop by just having a shortcut;
and it spins up the virtual environment;
and that spins up IE 6;
and I can then point that virtualised IE at my local machine where my “Hello World” ClickOnce application lives;
and it launches the setup process which launches the .NET Client Profile setup;
which runs the bootstrapper and then goes off to download the client profile itself and install it;
and once that is run up it launches my ClickOnce setup;
and runs my app;
( not that the app itself is worth running 🙂 ).
Having done this, I can just shut down the Virtual PC and remove the Undo Disk and I’m back to a nice state where I don’t have any .NET Framework installed on that virtualised XP and so I can start again. Nice – there’s something about the desktop integration here that makes it a lot more friendly (for me) than having to switch off into separate windows for the Virtual PC bits and I really like what they’ve done with Undo Disks here – for me it’s much nicer than being asked “Do you want to save/discard?” each time I shutdown the VPC.
Asides;
- I made a short screencast about the .NET Client Profile a while ago. It’s up here.
- I noticed (and watched) a video the other day about .NET Framework V4.0 and WPF features and there’s a discussion in there about how the .NET Client Profile becomes more applicable in .NET 4.0 so it might be worth taking a look at that video. It’s here.