Silverlight ClipToBounds

WPF’s ClipToBounds property is not available on Panels in Silverlight, which can lead to some design frustration. Using the new Interactions and Blend Behavior framework, it’s easy to whip up something nearly identical!

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interactivity;
//using Microsoft.Expression.Interactivity.Core;

namespace AutoClipperDemo
{
    public class AutoClipBehavior : Behavior<DependencyObject>
    {
        private RectangleGeometry _rectGeo;

        protected override void OnAttached()
        {
            base.OnAttached();

            if (base.AssociatedObject is FrameworkElement)
            {                 
                FrameworkElement fe = AssociatedObject as FrameworkElement;
                fe.SizeChanged += new SizeChangedEventHandler(AttachedObjectSizeChanged);
                
                _rectGeo = new RectangleGeometry();
                fe.Clip = _rectGeo;
                
                OnAdjustClip(fe, new Size(fe.ActualWidth, fe.ActualHeight));
            }            
        }

        protected virtual void OnAdjustClip(FrameworkElement fe, Size sz)
        {
            Rect rect = new Rect(0, 0, sz.Width, sz.Height);

            // it would be interesting to handle the border, but alas
            // we can't as it would clip the border as well. :)
            // best solution is to just put the border on or around
            // the panel being clipped by this
            _rectGeo.Rect = rect;
        }

        private void AttachedObjectSizeChanged(object sender, SizeChangedEventArgs e)
        {            
            OnAdjustClip(AssociatedObject as FrameworkElement, e.NewSize);
        }

        // always clean up after yourself ... remove anything that was attached
        // to prevent incorrect clipping and unnecessary event handlers
        protected override void OnDetaching()
        {
            base.OnDetaching();

            if (base.AssociatedObject is FrameworkElement)
            {
                FrameworkElement fe = AssociatedObject as FrameworkElement;
                fe.SizeChanged -= new SizeChangedEventHandler(AttachedObjectSizeChanged);
                fe.Clip = null;
                _rectGeo = null;
            }
        }
    }
}

image

<Border Grid.Column="4" Grid.Row="2" BorderBrush="White" BorderThickness="4" Background="#FF31C525">
    <i:Interaction.Behaviors>
        <local:AutoClipBehavior/>
    </i:Interaction.Behaviors>
    <Grid>
        <Ellipse Fill="#FF09570A" Stroke="Black" Height="250" Margin="91,138,-61,-46" VerticalAlignment="Bottom" Width="250"/>
    </Grid>
</Border>

Google’s Chrome Operating System

If you didn’t see the buzz about the Internet in the last 24 hours – where have you been? :)

Google announced officially that they are working on a new operating system, named Google Chrome OS (just rolls off the tongue doesn’t it?).

The few interesting points made in the announcement blog posting:

  1. Targeted initially at netbooks
  2. Open source, Linux based with a new windowing system and not Android based as this will work on ARM and x86 chips.
  3. Fast and lightweight – only a browser – all running within the Chrome web browser on modern standards
  4. No worries about drivers and software updates
  5. Released available fall 2009 initially

The point that interests me is #4, as the rest of it isn’t a surprise at all.

I’m not sure I understand how they’ll handle the various cameras, printers, mice, etc. that everyone will still want to use? That’s where Windows has a huge advantage today – the wide availability of hardware for Windows. If users can’t plug in their camera and just have it work, they’ll be frustrated (and print it of course). Thankfully, there are more standards around camera connections these days – but ….

What about RAW file formats for those of that don’t shoot JPEG for example? There are frequent updates from Adobe/Nikon/Canon/etc. to handle the constant stream of new file formats and changes that occur from each manufacturer. Maybe they’ve got this all figured out – but my experience with Linux in the past is that far too often a piece of hardware that worked fine with Windows isn’t recognized by the Linux.

I wonder what Microsoft will do about Silverlight? I’d be disappointed if it didn’t work on this new class of devices if it takes off. But, I also wonder about Flash support. Just because it’s Linux doesn’t mean that Flash will work. Google believes in HTML 5 so much that I can see them not being very “open” about making it work.

Arcade Billiards, the Source Code

Although my Mix09 entry didn’t place/win, as promised I’m posting the source code, as-is. It’s not the final completely condensed version that I actually submitted (as that version had carriage returns/line feeds, tabs, etc. all removed).

Download Source

As a consolation prize, I did receive a limited edition T-shirt just for entering (which admittedly, didn’t make the effort worth while – but, I had fun putting it all together nonetheless).

I’ve programmed in many nasty, strict environments over the years, but it felt really dirty to do this in c#:

DateTime _t, _aL, _tS;
B[] _b, _e;
Random _r = new Random();
double TW = 12, TH = 12, SY = 50, MW, MH, SA, G = .03, CSA, SSA;
Point A;
int CW = 20, CH = 40, TB = 21, _s, GM = 0, _c, BR;
Brush _o;
IsolatedStorageSettings _a;
delegate void PAD(Canvas c);

Yeah. Seriously, those were the variable names that I used to keep the file smaller.

I shrunk the standard Application class down to it’s bare minimum and used Lamda expressions everywhere:

public partial class App : Application
{
    public App()
    {
        Startup += ((s, e) => RootVisual = new Page());
        UnhandledException += ((s, e) =>
        {
            if(!System.Diagnostics.Debugger.IsAttached)
            {
                e.Handled = true;
            }
        });
        InitializeComponent();
    }
}

and …

Loaded += ((s, e) =>
{
    _a = IsolatedStorageSettings.ApplicationSettings;
    btnP.Click += ((o, a) =>
    {
        cMs.Visibility = Visibility.Collapsed;
        RG();
        GO();
    });

Last but not least, this was probably the silliest thing I did to stop needing to use the Canvas class everywhere directly (it was still necessary in some places):

class C : Canvas
{
}

You’ve got it. I derived from Canvas so I could just refer to the Canvas class as the letter “C”! Thankfully, it wasn’t sealed.

The code does the necessary math to compute an Isometric view of the game table so that the balls on the table are properly placed.

Fully condensed down, I think I ended up with 240 bytes to spare.

 

(Are you going to Mix09? Sounds like some great stuff will be announced!)