MetaDeveloper

Wednesday, May 06, 2009

Proper 0.2: INotify, DependencyProperty Support

{

Several years ago, in a land of Visual Studio 2005 and no CodeRush, I made a tool called Proper to automate the monotony of creating properties. You just type something like “int Foo;string Bar;” and you’d get basic property generation. You can use shortcuts to types by typing an undercore “_” character. For example, “i_” will pop up int, “dt_” would pop up DateTime (You can also create your own). It’s funny how the stuff that you’re half serious about can last so long – at the time I wanted to write something useful entirely in JavaScript and to experiment a little with JQuery.

The tool suffered neglect for the next few years until recently when I began working with Silverlight and was amazed at how a similar monotony (and more code!) accompanies using INotifyPropertyChanged and implementing dependency properties. I remembered my old tool and added support for generating them there. Here are some screenshots that should illustrate how it works (you select “advanced options” and then select a few checkboxes, in a nutshell). I’ll update the feature to report bugs – I’m sure there are a few. I also neglected to update it for VB.NET – I’ll do that over the next few weeks.

If you do spot a bug, let me know. There are a few new goals I have with the tool, the first of which is refactoring some of the embarrassing JavaScript I crufted together to make this work. I remember Kevin Dangoor talking about Embarrassment Driven Development (when your code is so embarrassing that you’re motivated to update it); that’s the one thing about JavaScript – you can’t hide the way things are constructed. :)

}

Friday, April 24, 2009

Using IronPython For Converters in Silverlight

{

 

Tim Heuer has a great intro post on Silverlight data binding and value converters. The concept is a really nice one but I’m not wild about having to write a class that implements the IValueConverter interface every time I need some ad-hoc tweaking of the values I get from being data bound and how I’d like to use them within XAML. What set me off this track was a case where I simply needed to invert a boolean – what should just be “not myvalue” ended up requiring a class, an interface, and so on.

Dynamic languages excel at this sort of thing and since they support the ability to evaluate code on the fly I thought it would make sense to write a single implementation of IValueConverter and host Python inside of it to evaluate binding expressions that are passed in. Here is what that might look like:

public class PythonExpConverter : IValueConverter
{
private ScriptEngine _engine;

public PythonExpConverter()
{

ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
setup.DebugMode = true;
var runtime = new ScriptRuntime(setup);
_engine = Python.GetEngine(runtime);

}

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object result;
string python = parameter.ToString()
.Replace("value", value.ToString());
try
{
result = _engine.Execute(python);
}
catch (Exception ex)
{
// pass, just use original value
result = value;
}
return result;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// same concept as above
return value;
}
}


No magic, just instantiate the Python runtime and then proceed to leverage it in the Convert phase by taking a string as the parameter for the conversion method. Use value as a keyword in your Python expression to get at the value of the underlying data.  Once this is added as a static resource, you can leverage it in many ways. For example, if I had a class “Person”:



public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool OnVacation { get; set; }
public double Balance { get; set; }
}


Let’s say I’m binding to an instance of Person (yeah, very contrived) with the following template conversions:

1. Uppercase last name.


2. If OnVacation is true, disable a link to their schedule.


3. Format balance using some currency specific format.


Here is the XAML that leverages my single converter for all of the above:



<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="First Name" Width="100" />
<TextBlock Text="Last Name" Width="100" />
<TextBlock Text="Is Active" Width="100" />
<TextBlock Text="Rating" Width="100" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" Width="100" />
<TextBlock Text="{Binding LastName, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'value\'.upper()}" Width="100" />
<HyperlinkButton Width="100" NavigateUri="http://foo" Content="View"
IsEnabled="{Binding OnVacation, Converter={StaticResource PythonExpConverter}, ConverterParameter=not value}" />
<TextBlock Text="{Binding Balance, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'%2.2f\' % value}" Width="100" />
</StackPanel>
</StackPanel>


This is a very powerful approach since the limitations you hit will probably be born by a limitation in skill with Python or your dynamic language of choice rather than the approach. 



}

Monday, March 23, 2009

Almost Famous

{

Yours truly, looking embarrassed in the middle.

 

Here is the link to Phil's write up.

}

Friday, March 20, 2009

Voidspace on Dot Net Rocks

{

Michael Foord, aka Voidspace, is on a Dot Net Rocks episode talking about IronPython.

}

Wednesday, March 04, 2009

Currying with C# and Algotron

{

Friend and coworker Algotron just posted an intro and sample of currying with C#. I decided to try out currying with the idea of successive regular expressions on a string array - I found it easy to approach first with anonymous delegate syntax and then use lambda expressions. Once this was in place it was easy to understand the use of an extension method to curry any binary function. 

Func<string, string[], Func<string, string[]>> fil = 
delegate(string pattern, string[] lines){
return delegate(string pattern2)
{
return lines
.Where(p=> Regex.IsMatch(p, pattern))
.Where(p => Regex.IsMatch(p, pattern2))
.ToArray();
};
};


Func<string, string[], Func<string, string[]>> regFil =
(pattern, input) =>
(pattern2) =>
input
.Where(p => Regex.IsMatch(p, pattern))
.Where(p => Regex.IsMatch(p, pattern2))
.ToArray();

// assume some address data
string[] data = new string[]{"1234 Somewhere", "this", "777 dakota"};

var filterNumeric = regFil(@"\d", data); // make sure it has a number
var filterUCase = filterNumeric("[A-Z]"); // make sure it has an uppercase character

Console.Write(String.Join(",", filterUCase));


That's cool stuff, worth looking at for a while to try to understand.



}

Tuesday, March 03, 2009

IronPython + SilverlightFX

{

SilverlightFX is an interesting library for declaratively attaching behaviors to objects in XAML. People new to the Silverlight world will like how they can use it to get simple animations out of simple code. Here's a step by step:

1. If you don't have it done already, set up an IronPython / Silverlight project.

2. Download SilverlightFX

3. Copy SilverlightFX binaries into your /app directory.

3. Edit the AppManifest.xaml to include the SilverlightFX binaries. Here is an example:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
RuntimeVersion="2.0.31005.00"
EntryPointAssembly="Microsoft.Scripting.Silverlight"
EntryPointType="Microsoft.Scripting.Silverlight.DynamicApplication">
<Deployment.Parts>
<!-- Add additional assemblies here -->
<AssemblyPart Source="Microsoft.Scripting.ExtensionAttribute.dll" />
<AssemblyPart Source="Microsoft.Scripting.Silverlight.dll" />
<AssemblyPart Source="Microsoft.Scripting.Core.dll" />
<AssemblyPart Source="Microsoft.Scripting.dll" />
<AssemblyPart Source="IronPython.dll" />
<AssemblyPart Source="IronPython.Modules.dll" />
<AssemblyPart Source="System.Windows.Controls.dll" />
<AssemblyPart Source="System.Windows.Controls.Data.dll" />
<AssemblyPart Source="Silverlight.FX.dll" />
</Deployment.Parts>
</Deployment>


4. Edit your app.xaml file to include references to the SilverlightFX namespaces. Here is an example:



<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="System.Windows.Controls.UserControl"
xmlns:fxui="clr-namespace:Silverlight.FX.UserInterface;assembly=Silverlight.FX"
xmlns:fxeffects="clr-namespace:Silverlight.FX.UserInterface.Effects;assembly=Silverlight.FX"
>


5. Party on with some declarative effects.



<Border Grid.Row="1" x:Name="redRect" Opacity="0.2">
<TextBlock x:Name="outPut" TextWrapping="Wrap"
Text="Lorem ipsum dolor sit amet,..." />
<fxui:Interaction.Behaviors>
<fxui:HoverEffect>
<fxeffects:Fade FadeOpacity="1" />
</fxui:HoverEffect>
</fxui:Interaction.Behaviors>
</Border>


6. Read Nikhil's related blog entries.



}

Thursday, February 26, 2009

DLR + IronPython + Silverlight in 5 Steps (with pictures)

{

A simple step by step1.

1. Download the Silverlight DLR SDK

2. Map the binaries (the folder with Chiron2 et. al.)  in your PATH Environment variable.

3. Download this starter template.

4. Run chiron /w from the command line in the directory of the starter.



a) Make sure you're in the correct folder
b) The command is
chiron /w
c) You'll get a message that Chiron is serving at http://localhost:2060a

5. Navigate to http://localhost:2060 and hit index.html to see what's up.



 
The starter3 should make it easy to get up and running. Open the app.py and app.xaml files and you will be able to modify the xaml and write code to customize it into your own creation.

1. Michael Foord aka Voidspace is the guy when it comes to IronPython. He wrote a book on it. He has a "getting started" tutorial that is much more extensive if you want more details. His tutorial isn't as terse so I thought I'd write this one for people who just want a step by step before poking around. There are other people like JimmyThinking who offer a lot of help to beginners but lean towards IronRuby.

2. The name Chiron for a tool makes me think about a few things: first, being born out of time since most BigCo shops today name computers and tools in a hollow, mechanistic fashion. In the salad days of computing on Unix, tools had cool names like ed or yacc. The second thing I think is that Dmitri (and I'm sure there's an "et. al.") must be a cool, interdisciplinary fellow to come up with a name like that.

3. The exchange in the sample is from Swahili classes at Rusinga Primary School in Nairobi.

}