MVVM, Silverlight, WPF

Sneak Preview Of CinchV2 In Action

Over the course of this weekend I finished up the CinchV2 WPF demo app, and am now working on the Cinch V2 Silverlight 4 demo app.

I am really really thrilled with how it has all worked out.

Here is a screen shot of the WPF app running:

wpfDemo

And here is one of the Views open at design time in Blend observe that cool design time data.

wpfBlend1

Ah, excellent. So I just have to do the Silverlight 4 demo app, and then I can write the 1st of the articles and give you all the code.

I have to say I am really really really pleased with what I can now do with CinchV2.

WPF

Bigup And Thanks To My Readers

It seems I did rather well in last months codeproject monthly competitions, where my Timeline WPF control won both the C# category and the overall best article category.

I am sure this is all thanks to most of you that read my blog, so a massive thanks to you all.

To thank you all I plan on releasing a tirade (a veritable tsunami) or articles on the new version of Cinch that I have developed. I honestly do believe it is my best work to date (I know I say that every time, but this time I mean it, well until the next time I guess).

So watch out for that, I have done the code base, and am about 50% through the demo apps (WPF and SL), and then I will be starting the articles.

Anyway thanks ye all

MVVM, Silverlight, WPF

What the heck is Sacha doing, why so quite

Some of you may have noticed that my blog has been a bit quite of late, let me just tell you that is not because I am being lazy, quite the opposite in fact.

I am really really busy now putting finishing touches to my MVVM framework, Cinch V2, which I have just finished the codebase for. I am really really really thrilled about how it has worked out, and I now consider it to be an awesome MVVM framework that is capable of doing pretty much everything that I have encountered at work whilst working on a very large LOB app using WPF, for a FX (finance) company.

So that is what I have been doing, as I have hinted at in previous posts, I have made some big changes to Cinch for V2, so that is why it is taking a while, and also I have to create demo apps, one for WPF and one for SL, so that also takes time and then there are articles which serve as the documentation.

See it never ends, so please please just bear with me, I am on it, it just takes time.

Once I have the demo apps done and the 1st article I will be uploading the codebase to codeplex.

PS : I am now a dad, so that takes up a lot of time, and I am a lot more tired that I used to be, but I am still trying for you all.

C#, WPF

I need your votes

I have just noticed that one of my articles, WPF Timeline Control is up for this months Monthly C# and Overall best articles awards.

This article is something I spent a fair amount of time on, and I feel it is pretty useful if you are doing WPF.

If you like what I do, I would really appreciate your taking a minute to vote for my article

You can vote at here for C# article category :

http://www.codeproject.com/script/Surveys/VoteForm.aspx?srvid=1036

And you can also vote at here for overall category  :

http://www.codeproject.com/script/Surveys/VoteForm.aspx?srvid=1033

And if you feel you want to give my article WPF Timeline Control a vote that would be well received.

Thanks.

Current Work, MVVM, WPF

Cinch (Again)

As my last post on Cinch indicated I fixed a lot of stuff in the latest drop, there 1 or 2 areas where I forgot to fix things (though the code still works, but could have been improved, so I improved it).

I then had major headaches with SVN/Codeplex source code getting corrupted whilst I was trying to update codeplex, so I struggled with that for a long time on Saturday 08/05/2010.

So if you downloaded Cinch again, I would urge you to please download and use the latest drop where the codeplex realease tab states “All Fixed”.

As the comment indicates this has all fixes and is correct source control (SVN) wise.

I am now working on Cinch V2 which I think it going to be a much better API to work with.

Enjoy Cinch V1 for now, Ill keep you all post Re: Cinch V2.

There will also be a new demo app for Cinch V2 for both WPF and SL.

C#, Cinch, MVVM, Silverlight, WPF

Cinch news

For those of you that are using my Cinch MVVM framework framework I have some very good news for you. This weekend I did a lot of work to the framework in preparation for a massive overhaul I am just about to give Cinch to allow .NET 4/VS2010 / Mef support.

The changes for .NET 4/VS2010 / Mef support represent what I deem to be a new codebase, so that is bad news as there will be some breaking changes for current users, but I think the new version of Cinch will be a superior framework to use. And I expect it will be a while before most people make the jump to .NET 4/ vs2010 anyway.

The good news, is that I have made a lot of changes to Cinch V1 (WPF only) this weekend, which are as follows:

  • Made it so default Simple Logging Facade based logger, can be swapped out for another ILogger based logger, which will allow the dependency on Slf.dll to be removed if you do not choose to use SLF and instead write your own ILogger implementation and inject that. SLF is the default though, so for now Cinch has a dependency on SLF.
  • Made a new interface called IIOCProvider which allows the IOC Container to also be swapped out. The default is Unity, and Cinch currently uses a UnityProvider, again if you wish to write a IIOCProvider and pass that into the new Cinch base ViewModel constructors, you will be able to remove the dependency on Unity.  Unity is the default though, so for now Cinch has a dependency on Unity.
  • Gave the Mediator a massive overhaul, so it now allows lamda registration/unregister. It also provides asynchronous NotifyCollegues methods. There is also a Mediator singleton which may be accessed using the Mediator.Instance singleton. The ViewModelBase class does a register on construction and unregister on Dispose.
  • Changed the MediatorMessageSinkAttribute, so that users no longer need to specify the parameter type. This is a breaking change, sorry. The Cinch V1 demo code shows the new way of dealing with the Mediator attributes.
  • Altered the way the IUIVisualizer service is initialised. This is now done with a callback Action<IUIVisualizerService> delegate. This is a breaking change, sorry. The Cinch V1 demo code shows the new way of dealing with the IUIVisualizer service.
  • Provided properties in ViewModelBase for IsLoaded/IsUnloaded/IsActivated/IsDeactivated. Though overriders if the virtual view lifetime methods will have to remember to call base methods in order  for these new properties to work
  • Made various other small changes, basically I tried to do all oustanding issues/discussions and patches from the Cinch codeplex site.

So that should help those using VS2008, these changes are available right now

So what have I got in store for you with the next version, well I plan to get rid of 3rd party IOC containers entirely and use MEF. There will also be much much better Blend support, and design time data considerations will be paramount in what I am trying to achieve.

The view lifecycle attached commands will also be made into a ViewAware service that the viewmodels can use.

This is going to be a big set of changes, and I will also be trying to get this all to work for Silverlight 4 and upwards too, so it could take me a little while, but I am looking into it.

In the mean time I will update all the existing Cinch codeproject articles.

NOTE : One thing to note is that when you download Cinch after I have it all working it will contain

  1. V1 which is targeted at Vs2008 and WPF only
  2. V2 which is target at Vs2010 and will be for WPF and SL

Stay tuned, I will be writing a series of articles on Cinch v2 when I have it done.

C#, CodeProject, Silverlight, WPF

Messing With The New PathListBox

Blend 4 is really cool, the best version yet (well duh, of course it is Sacha).

Anyway one of the things that caught my eye is that Blend 4 now comes with some pre-canned shapes, such as Arrow etc etc, this is good news for me, as I have all the graphics skills of a dead anteater.

See here :

shapes[1]

So that is cool, the other thing that caught my eye is the PathListBox, which is a new control which is for SL and WPF. Finally WPF gets some love.

You may have actually seen this PathListBox control as Mix, or as I did at a SL launch party, where there was a very fancy ListBox that displayed text around a circle. It looked way cool, so I decided to have a play with the new boy on the block and see what I could do with it in 1-2 hours.

It is a great control actually. So how do you use it.

Well to start with I did this I dragged a PathListBox from the controls tab in the Blend assets onto the stage.

Path1[1]

Then I simple created a Ellipse on the stage. I put the PathListBox in the upper left corner out of the way, and the Ellipse in the middle. I then went about setting the Ellipse as the LayoutPath for the PathListBox, which you can do by using the drag and drop target to pick a element on the stage in Blend.

Path2[1]

To add items to the PathListBox I am using a bit of code behind, but the PathListBox does allow any UI element to be an item so if you were to drag Buttons to the PathListBox after you had picked the Ellipse as its LayoutPath, you would see the Buttons arranged in an Ellipse.

Ok so like I say I have some items added via code behind, so then it was onto how I wanted the items laid out, which again is all done inside Blend using the LayoutPaths applet. This has various settings I urge you to play with these, you can control orient to path, padding, start/span percentage etc etc

Path3[1]

This is all pretty cool, but what I wanted to try and create was as close as I could to a circle with some text around it. To do this I needed a DataTemplate and a ItemContainerStyle, both of which I created in Blend.

Here is what I came up with

Using Ellipse as a Path

Path4[1]

Using Path as a Path

Path5[1]

The full code listing for this is available is as follows, the things of note are the DataTemplate and the PathListBoxItem Style. Unfortunately I do not know of any way in Blend to do a RelativeSource binding, so I had to slip into a bit of code to do the Trigger on the DataTemplate.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ec="http://schemas.microsoft.com/expression/2010/controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"
    x:Class="WpfApplication1.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Background="Black"
    UseLayoutRounding="True"
    Width="800" Height="800">

<Window.Resources>
    
        <DataTemplate x:Key="listBoxItemTemplate">
            <StackPanel HorizontalAlignment="Right" Width="150"
                RenderTransformOrigin="0.5,0.5" Background="Transparent">
                <StackPanel.RenderTransform>
                    <RotateTransform Angle="-90" CenterX="0.5" CenterY="0.5"/>
                </StackPanel.RenderTransform>
                <Label x:Name="lbl" Content="{Binding}" Padding="0,2,13,2" 
                    HorizontalAlignment="Left" 
                    HorizontalContentAlignment="Left"
                    Foreground="White" FontSize="10" Width="150">
                </Label>
            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource=
                    {RelativeSource Mode=FindAncestor, 
                    AncestorType={x:Type ListBoxItem}, AncestorLevel=1}, 
                    Path=IsSelected}" 
                    Value="True">
                    <Setter TargetName="lbl" Property="Foreground" Value="Orange"/>
                </DataTrigger>
            </DataTemplate.Triggers>
            
        </DataTemplate>
        
        
        <Style x:Key="PathListBoxItemStyle1" TargetType="{x:Type ec:PathListBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ec:PathListBoxItem}">
                        <Grid Background="{TemplateBinding Background}" 
                        RenderTransformOrigin="0.5,0.5">
                            <Grid.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform/>
                                    <RotateTransform Angle="{Binding OrientationAngle, 
                                    RelativeSource={RelativeSource TemplatedParent}}"/>
                                    <TranslateTransform/>
                                </TransformGroup>
                            </Grid.RenderTransform>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.Opacity)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0.6"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" 
                                            To="0.35" Storyboard.TargetProperty="Opacity" 
                                            Storyboard.TargetName="fillColor"/>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.Opacity)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[0].(ScaleTransform.ScaleX)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[0].(ScaleTransform.ScaleY)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[3].(TranslateTransform.X)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0.55" 
                                            Storyboard.TargetProperty="Opacity" 
                                            Storyboard.TargetName="contentPresenter"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0.75" 
                                            Storyboard.TargetProperty="Opacity" 
                                            Storyboard.TargetName="fillColor2"/>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[0].(ScaleTransform.ScaleX)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[0].(ScaleTransform.ScaleY)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames 
                                            Storyboard.TargetProperty="(UIElement.RenderTransform).
                                            (TransformGroup.Children)[3].(TranslateTransform.X)" 
                                            Storyboard.TargetName="contentPresenter">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" 
                                            Storyboard.TargetProperty="Visibility" 
                                            Storyboard.TargetName="FocusVisualElement">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Rectangle x:Name="fillColor" Fill="{x:Null}" 
                            IsHitTestVisible="False" 
                            Opacity="0" RadiusY="1" RadiusX="1"/>
                            <Rectangle x:Name="fillColor2" Fill="{x:Null}" 
                            IsHitTestVisible="False" 
                            Opacity="0" RadiusY="1" RadiusX="1"/>
                            <ContentPresenter x:Name="contentPresenter" 
                            ContentTemplate="{TemplateBinding ContentTemplate}" 
                            Content="{TemplateBinding Content}" 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            Margin="{TemplateBinding Padding}" 
                            RenderTransformOrigin="0.5,0.5" OpacityMask="{x:Null}">
                                <ContentPresenter.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform CenterX="0" CenterY="0.5"/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>
                            <Rectangle x:Name="FocusVisualElement" RadiusY="1" 
                            RadiusX="1" Stroke="{x:Null}" StrokeThickness="1" 
                            Visibility="Collapsed"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>    
    
</Window.Resources>

    <Grid x:Name="LayoutRoot" Width="800" Height="800">
        <ec:PathListBox x:Name="lstBox" Margin="0" 
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            ItemTemplate="{StaticResource listBoxItemTemplate}"
            Width="100" Height="100" 
            d:LayoutOverrides="Width, Height, Margin" 
            ItemContainerStyle="{DynamicResource PathListBoxItemStyle1}">
            <ec:PathListBox.LayoutPaths>
                <ec:LayoutPath SourceElement="{Binding ElementName=path}" 
                Padding="2" Distribution="Even" Orientation="OrientToPath"/>
            </ec:PathListBox.LayoutPaths>
        </ec:PathListBox>
        <Ellipse x:Name="ellipse"
         Margin="247,157,253,343" Width="300" Height="300" 
         d:LayoutOverrides="VerticalAlignment"/>
        <Path x:Name="path" Data="M439,268 C519,374 439,476.5 439,476.5 L368.25091,547.25" 
        Margin="368.25,268,324.444,251.75" 
        StrokeStartLineCap="Flat" Stretch="Fill" StrokeEndLineCap="Flat" 
        StrokeThickness="1" StrokeMiterLimit="10" StrokeLineJoin="Miter" 
        UseLayoutRounding="False"/>
        <Button x:Name="btnUseEllipse" Content="Use Ellipse" 
        HorizontalAlignment="Right" Height="28" Margin="0,22,253,0"
         VerticalAlignment="Top" Width="98"/>
        <Button x:Name="btnUsePath" Content="Use Path" 
        HorizontalAlignment="Right" Height="28" Margin="0,22,139,0" 
        VerticalAlignment="Top" Width="98"/>
    </Grid>
</Window>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }And as always here is a small demo application for you:

Blend4 RC PathListBox Demo.zip