Whilst work­ing on an image view I needed the abil­ity to bind the value of a Slider to a Scale­Trans­form as a per­cent­age value and at the same time dis­play the value of the slider in a label. So for a zoom range from 1% to 250% you would usu­ally set the Min­i­mum and Max­i­mum prop­erty of your Slider to 0.01 and 2.5 respec­tively, by then you wouldn’t be able to dis­play the zoom value as a per­cent­age, e.g. Zoom 148%.

So to get around this lim­i­ta­tion, in the end I used the range 1 to 250 for the Slider and added another Scale­Trans­form with ScaleX and Sca­leY set to 0.01, like this:

<StackPanel x:Name="LayoutRoot" Background="Gray">
    <StackPanel Orientation="Horizontal">
        <TextBlock Margin="5,5,10,5">Zoom</TextBlock>
        <TextBlock Margin="5,5,0,5" Text="{Binding Path=Value, ElementName=sldZoom, Mode=OneWay}"/>
        <TextBlock Margin="0,5">%</TextBlock>
    </StackPanel>

    <Slider x:Name="sldZoom" Orientation="Horizontal" Minimum="1" Maximum="250" Value="100"/>

    <Image Source="bingonet.png" RenderTransformOrigin="0, 0">
        <Image.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="0.01" ScaleY="0.01"/>
                <ScaleTransform>
                    <ScaleTransform.ScaleX>
                        <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                    </ScaleTransform.ScaleX>
                    <ScaleTransform.ScaleY>
                        <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                    </ScaleTransform.ScaleY>
                </ScaleTransform>
            </TransformGroup>
        </Image.RenderTransform>
    </Image>
</StackPanel>
Share

Of all the cur­sors that we come across on a daily basis, the grab image and grab­bing image cur­sors are two notable absen­tees in the list of sup­ported cur­sors in WPF/Silverlight.

So if you hap­pen to need these two cur­sors as I did ear­lier in the day, then here’s a few easy steps to get you going:

1. Down­load the grab.cur and grabbing.cur files from here and here.

2. Include them in your project, under a Resources/Cursors folder, like this:

image

3. Make sure the Build Action for both is set to ‘Resource’ (which is sim­i­lar to Embed­ded Resource, except Resource is intended for WPF/Silverlight and Embed­ded Resource is intended for older technologies):

image

4. You won’t be able to put them in as Resources directly, but you can put a ref­er­ence to them using dummy TextBlock controls:

<UserControl.Resources>
    <ResourceDictionary>
        <TextBlock x:Key="CursorGrab" Cursor="Resources/Cursors/grab.cur"/>
        <TextBlock x:Key="CursorGrabbing" Cursor="Resources/Cursors/grabbing.cur"/>
    </ResourceDictionary>
</UserControl.Resources>

5. Now you can retrieve the ref­er­ences to these cur­sors in code like this:

_grabCursor = ((TextBlock) Resources["CursorGrab"]).Cursor;
_grabbingCursor = ((TextBlock) Resources["CursorGrabbing"]).Cursor;
Share

I was hav­ing an email con­ver­sa­tion with a friend on WPF yes­ter­day and he sug­gested putting it into a blog post after I went on and on for a bit (sorry Raj!).

Hav­ing spent some time learn­ing Sil­verlight (which is a sub­set of WPF for the web, Microsoft’s equiv­a­lent of Flash) I have really come to like the new pro­gram­ming model in WPF and how eas­ily it allows you to do things that were sim­ply impos­si­ble to do in Win­Forms (ever tried to put a rounded cor­ner to a rec­tan­gle anyone?).

To those not famil­iar with WPF, it’s pow­ered by DirectX so you get hard­ware accel­er­a­tion and can use fea­tures such as trans­parency, gra­di­ents and trans­for­ma­tions. Its pro­gram­ming model enables clear sep­a­ra­tion of the UI from busi­ness log­ics because you now have to build your UI using a declar­a­tive lan­guage – XAML (Exten­si­ble Appli­ca­tion Markup Language).

The event model has also been revamped and it’s now pos­si­ble to ‘route’ an event so it orig­i­nates from one ele­ment but is raised by another. WPF sup­ports sev­eral types of routed events, but Sil­verlight only allows bub­bled events which cas­cades up the con­tain­ment hier­ar­chy from deeply nested ele­ment to its containers.

Why is Declar­a­tive UI better?

Whilst declar­a­tive UI is some­thing of a shock to the sys­tem to most of us (web devel­op­ers not included!) it actu­ally makes per­fect sense because it helps solve one of the biggest prob­lems in UI devel­op­ment – busi­ness logic embed­ded in UI.

A declar­a­tive UI makes it harder to write busi­ness logic into the UI because you’re writ­ing less code. How­ever, it’s not about sep­a­ra­tion of tiers, but sep­a­ra­tion of con­cerns, so when you find prob­lems there is a smaller blast radius! Which again, all comes down to loose cou­pling — the same thing peo­ple are try­ing to achieve with IoC and Depen­dency Inver­sion from a depen­dency point of view.

So all’s well with WPF and indus­try vet­er­ans are all rav­ing about it (there’s a num­ber of shows on Dot­NetRocks alone which cov­ers WPF and Declar­a­tive UI) so why is there still a dis­tinct lack of real-world apps out there? Besides the odd project on Code­Plex like Fam­ily Show and Scott Hanselman’s BabySmash, I haven’t found too many exam­ples out there (it’s a shame Pho­tol­ogy’s dead.. :-( )

Prob­lems:

I think there are two main rea­sons why a lot of peo­ple are still not adopt­ing WPF, nei­ther has any­thing to do with the tech­nol­ogy itself which is like a fancy new drug which makes you never want to go back! And there are plenty of indus­try sup­port both in terms of third party sup­port (well known UI con­trols pro­duc­ers like teleriks, infrag­is­tics already offer numer­ous UI pack­ages for WPF and Sil­verlight) and back­ing from the indus­try veterans.

1. it’s still fairly young

Hav­ing only made it into the core .Net plat­form since .Net 3.0 (nov 2006) it is still fairly new to most devel­op­ers con­sid­er­ing that most peo­ple are still happy using .Net 2.0 (I know this is def­i­nitely true in the banking/enterprise world!) which equates to:

  • a lack of exist­ing exper­tise in the field, mak­ing it hard for would-be adopters because it adds to the cost of adop­tion in time and expense regard­less of their strat­egy to acquire these exper­tise, i.e. new recruit vs. train­ing exist­ing staffs
  • an addi­tional risk with adopt­ing WPF because you have to first migrate your plat­form to .Net 3.0, which, should be min­i­mal because it’s really just an add-on to the .Net 2.0 frame­work. But then again, “why fix what’s not broken?”

2. it’s only a viable option for new developments

Because WPF intro­duces a com­pletely new set of tech­nolo­gies and a new pro­gram­ming model to boot, it’ll require sig­nif­i­cant time and effort to con­vert an exist­ing UI appli­ca­tion. This means WPF is only worth con­sid­er­ing for new developments.

The future:

As with all things Microsoft, there’s a strong focus on enter­prise users and I’m sure their rep­re­sen­ta­tives would con­tinue to make a push for their part­ners to adopt WPF and dare I say once they decide to jump on board MS would have a prob­lem stop­ping them from com­ing back for more! Yup, WPF is that good!

With the .Net plat­form going strong as ever (men­tioned in 44% of devel­oper jobs posted in the UK in the last 6 months), the uni­ver­sal adop­tion of WPF as the de facto stan­dard for devel­op­ing UI appli­ca­tion should only be a mat­ter of time. Given the risk-adverse nature of large enter­prises (who, given their size and finan­cial mus­cles, have more say on tech­nol­ogy trends than any­one else), it’s no sur­prise to me that WPF has not really caught on, but as more and more enter­prises jump on the WPF band­wagon they’ll in turn increase the size of the tal­ent pool avail­able to oth­ers and really set the ball rolling.

Fur­ther reading:

WindowsClient.Net

Prism: pat­terns & prac­tices Com­pos­ite Appli­ca­tion Guid­ance for WPF and Sil­verlight site

Share