Dynamic Script Control

June 11th, 2008 casualjim Posted in xaml, IronPython, Silverlight, IronRuby 1 Comment »

Both Silverlight and WPF use XAML markup to describe their user interface.  As I’m currently writing my chapter on WPF for my book IronRuby In Action and I want to use some xaml that has been generated before for a different project but with an IronRuby class to load the xaml I’m in trouble. This is because you can declare assembly references in the xml namespace declarations so you can use the types in that assembly from xaml. 

The DLR based languages don’t compile into static assemblies and this means that you can’t use those xml namespace definitons to reference your assemblies.  I wrote a fairly trivial control that acts like a hook for DLR based controls in the XAML tree.

You can check it out at codeplex.
http://codeplex.com/dynamicscriptcontrol

The idea behind this control is that you can "hook" your DLR based control into the visual tree by setting some properties.  You can set properties on the DLR based control by setting the Attributes property on the DynamicScriptControl

Let’s look at a quick example:

1. The ruby file defining a custom TextBox. But you can do whatever  you want in that ruby file of course.

dynamic_script_control_rubyscript

All this textbox does is preset it’s text property to "I’m prefilled"

2. The xaml for the window

dynamic_script_control_window_xaml 

You first declare a namespace for the assembly that has the DynamicScriptControl. Next I have a StackPanel that contains 2 DynamicScriptControls. The first just contains the 2 mandatory properties. We need to know which class you want to instantiate in the file you provide by setting the ScriptFile property. This script file property is a path to your ruby file in my case prefilled_text_box.rb.
The second DynamicScriptControl is one where I want to initialize the control with my own text property. To declare those properties you have to add them to the Attributes collection of the DynamicScriptControl. At this moment it’s not smart enough to know which datatype you give it so you can specify a format string which was necessary in this case because text is a string.

3. The result

dynamic_script_control_window

Michael Foord the author of IronPython In Action will provide the python integration in this control.

There was a release of the Dynamic Silverlight SDK earlier this week which contained the necessary source code files to compile a common DLR for both IronRuby and IronPython.  That is what makes it possible to support multiple scripting languages from the start. 

I’ve hosted the source code on google and you can find that at:

http://code.google.com/p/dynamic-script-control

AddThis Social Bookmark Button

Silverlight / IronRuby using controls (Part 2)

April 17th, 2008 casualjim Posted in Silverlight, IronRuby 1 Comment »

I’m sorry I didn’t post the last 2 days, but we’re back with a new post. In my previous posts (1, 2) we didn’t use the files as they are generated by the little DSL script, this was chosen purposely so you would know that you don’t really need those files.

Today we are going to use the files that get generated by the DSL script. We’re going to add some classes to silverlight.rb to enable a nicer api for generating elements from ruby.  We left off last time with some code to generate 3 elements. That code wasn’t the prettiest code I’ve ever seen, apparently John Lam agrees and he has written a little DSL script for generating those elements. In today’s post we’ll be using that little script to generate the StackPanel etc.

Download the completed code

Just a refresher, here’s the code we ended up with the last time.

Code (ruby)
  1. requireSystem.Windows.Controls,’ +
  2. ‘ Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′
  3. requireSystem.Windows.Controls.Extended, ‘+
  4. ‘Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′
  5.  
  6. include System::Windows
  7. include System::Windows::Controls
  8.  
  9. class FrameworkElement
  10.         def method_missing(m)
  11.                 find_name(m.to_s.to_clr_string)
  12.         end
  13. end
  14.  
  15. xaml = Application.current.load_root_visual(Canvas.new, "app.xaml")
  16. textblock = xaml.my_textblock
  17.  
  18. panel = StackPanel.new
  19. panel.margin = Thickness.new 50
  20. panel.orientation = Orientation.horizontal
  21.  
  22. button = Button.new
  23. button.content = ‘Push Me’
  24. button.font_size = 18
  25. button.margin = Thickness.new 10
  26.  
  27. waterbox = WatermarkedTextBox.new
  28. waterbox.font_size = 18
  29. waterbox.margin = Thickness.new 10
  30. waterbox.width = 200
  31. waterbox.watermark = ‘Type Something Here’
  32.  
  33. panel.children.add(button)
  34. panel.children.add(waterbox)
  35.  
  36. xaml.children.add(panel)
  37.  
  38. button.click do |sender, e|
  39.         textblock.text = waterbox.text
  40. end

Let’s start replacing that code with something a little nicer. Open up the silverlight.rb file in your app folder and add the require directives at the top of your file. Next we’re going to need the Wpf::Builders module created by John Lam it’s included in the download.  We’re going to need to add the following code in the silverlight.rb file:

Code (ruby)
  1. module Wpf
  2.   module Builders
  3.     def name_collector
  4.       @___name_collector_
  5.     end
  6.  
  7.     def [](name)
  8.       name_collector[name]
  9.     end
  10.  
  11.     def inject_names(obj)
  12.       name_collector.each_pair do |k, v|
  13.         obj.instance_variable_set("@#{k}".to_sym, v)
  14.       end
  15.     end
  16.  
  17.     def evaluate_properties(obj, args, &b)
  18.       obj.instance_variable_set(:@___name_collector_, name_collector)
  19.  
  20.       args.each_pair do |k, v|
  21.         if k == :name
  22.           name_collector[v] = obj
  23.         end
  24.         obj.send :"#{k.to_s}=", v
  25.       end
  26.  
  27.       if obj.respond_to? :name
  28.         name_collector[obj.name] = obj unless obj.name.nil?
  29.       end
  30.  
  31.       obj
  32.     end
  33.  
  34.     def add_object_to_name_collector(collection, obj, args = {}, &b)
  35.       obj = evaluate_properties(obj, args, &b)
  36.       obj.instance_eval(&b) unless b.nil?
  37.       collection.add obj
  38.       obj
  39.     end
  40.  
  41.     def add_class_to_name_collector(collection, klass, args = {}, &b)
  42.       obj = evaluate_properties(klass.new, args, &b)
  43.       obj.instance_eval(&b) unless b.nil?
  44.       collection.add obj
  45.       obj
  46.     end
  47.  
  48.     def assign_to_name_collector(property, klass, args = {}, &b)
  49.       obj = evaluate_properties(klass.new, args, &b)
  50.       obj.instance_eval(&b) unless b.nil?
  51.       self.send property, obj
  52.       obj
  53.     end
  54.   end
  55.  
  56.   def self.build(klass, args = {}, &b)
  57.     obj = klass.new
  58.     obj.instance_variable_set(:@___name_collector_, {})
  59.  
  60.     args.each_pair do |k, v|
  61.       if k == :name
  62.         obj.name_collector[v] = obj
  63.       end
  64.       obj.send :"#{k.to_s}=", v
  65.     end
  66.  
  67.     obj.instance_eval(&b) if b != nil
  68.     obj
  69.   end
  70. end

That module takes care of dispatching the correct property names etc. Now that we have the module we can alter the SilverlightApplication a little bit. Let’s add a method add to that class that will be our entry point into the Wpf::Builders dsl.

Code (ruby)
  1. class SilverlightApplication
  2.  
  3.   def add(klass, args = {}, &b)
  4.     obj = Wpf.build klass, args, &b
  5.     children.add obj
  6.   end

Ok we still need to monkey patch a couple other classes before we’re ready to go. The first thing we see is that StackPanel has a setter method for Margin that takes an instance of Thickness. The property margin is defined on FrameworkElement, so that we can use it on every object that inherits of FrameworkElement. We’re also going to be addressing objects by their name. Not all of them have a name setter method so we’re going to ensure that all of them have one by monkey patching DependencyObject

Code (ruby)
  1. class FrameworkElement
  2.   alias_method :old_margin=, :margin=
  3.   def margin=(value)
  4.     self.old_margin = Thickness.new *value
  5.   end
  6.  
  7.   def method_missing(m)
  8.     find_name(m.to_s.to_clr_string)
  9.   end
  10. end
  11.  
  12. class DependencyObject
  13.   def name=(value)
  14.     self.set_value(FrameworkElement.NameProperty, value.to_clr_string)
  15.   end
  16. end

This gives us the ability to set margins as if it were normal integer values.

The next thing we see is that there is an Orientation property that we’re going to set and that seems to take an enumeration of some sort. To accomplish this we’re going to monkey patch StackPanel.

Code (ruby)
  1. class StackPanel
  2.  
  3.   alias_method :old_orientation= , :orientation=
  4.  
  5.   def orientation=(value)
  6.  
  7.     self.old_orientation= case value
  8.     when :horizontal
  9.       Orientation.horizontal
  10.     when :vertical
  11.       Orientation.vertical
  12.     end
  13.   end
  14. end

We’re almost there don’t worry :). The next thing we see is that we need to be able to add child elements to that element. A StackPanel, DockPanel and so forth are all children of Panel so let’s patch Panel and enable this for more containers. To do this we need to include the module Wpf::Builders in the Panel class and we need to make sure we have all the necessary methods in there that will allow us to add children to that Panel.

Code (ruby)
  1. class Panel
  2.   include Wpf::Builders
  3.  
  4.   def add(klass, args = {}, &b)
  5.     add_class_to_name_collector(children, klass, args, &b)
  6.   end
  7.  
  8.   def add_name(name, obj)
  9.     name_collector[name] = obj
  10.   end
  11.  
  12.   def add_obj(obj)
  13.     add_object_to_name_collector(children, obj)
  14.   end
  15.  
  16. end

We’ve now got us a little DSL for generating the necessary elements for this demo. All that is left to do now is write the initialize method in app.rb so that we get the same result as the last demo. Below we’ve got the content of the app.rb file

Code (ruby)
  1. require "Silverlight"
  2.  
  3. class App < SilverlightApplication
  4.   use_xaml
  5.  
  6.   def initialize
  7.     add StackPanel, :margin => 50, :orientation => :horizontal do
  8.  
  9.       add Button, :content => ‘push me’,
  10.                   :name => ‘my_button’,
  11.                   :font_size => 18
  12.       add WatermarkedTextBox,
  13.                   :font_size => 18,
  14.                   :margin => 10,
  15.                   :name => ‘my_waterbox’,
  16.                   :width => 200,
  17.                   :watermark => ‘Type something here’
  18.     end
  19.  
  20.     my_button.click do |sender, e|
  21.       my_textblock.text = my_waterbox.text
  22.     end
  23.   end
  24.  
  25. end
  26.  
  27. App.new

I hope you can see that Silverlight and IronRuby can really work together to help you build some cool things easily. The next post will deal with some animation, hope to see you there ;)

del.icio.us Tags: ,

Technorati Tags: ,

AddThis Social Bookmark Button

Silverlight / IronRuby using controls

April 15th, 2008 casualjim Posted in Silverlight, IronRuby 1 Comment »

In yesterdays post we covered the very basics of using IronRuby with Silverlight. Today we’re going to look at how we can use some of the basic controls that have been released for silverlight. One of the cool things about the controls is that Microsoft released the source code for them. Along with this source code they also released a test framework for testing your own controls. I think that is pretty cool :)
Shawn Burke explains how to use the testing framework they built for silverlight controls. In his blog post he also points you to the correct location for downloading the bits you need.

The next thing that is really cool about using silverlight is that it’s so easy to change the appearance of a silverlight control by using skinning. Corrina Barber explains how to go about that and she also has 4 sets of skins for the standard controls available for download.
See online previews of each skin:

Are you still here? Great :) Let’s look at some simple examples of using the standard controls that come with the Silverlight SDK. We won’t look into skinning those controls yet but for now will just look at how to use some of them. Like yesterday we’re going to look at 2 examples one that uses predominantly xaml and one that uses mostly ruby.

You can view the completed examples online:

I got my Ruby In Steel to work again so in the code download I’ve included the Visual studio solution and project files.

Download the completed code

The first sample will be mostly using xaml. The first thing we need to do is create a silverlight application. Just like yesterday I’ve removed the silverlight.rb file, but unlike yesterday we are not done preparing our app yet. The controls we’re going to be using for our samples live in Microsoft.Silverlight.Controls.dll and Microsoft.Silverlight.Controls.Extended.dll. These dll’s can be found on my pc in C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client.  Copy those controls to the app folder of your application.  We’re now one step away from completing the preparations. The last thing we need to do is tell our application it requires the assemblies that contain the controls. To do this we need to add them in an AppManifest.xaml file. To generate such an AppManifest.xaml file we can use chiron with the parameters /m and /d:app

silverlight_controls_appmanifest

The file that got generated contains references to Microsoft.Silverlight.dll, as well as for the DLR (Microsoft.Scripting.dll) and for IronRuby (IronRuby.dll and IronRuby.Library.dll). We need to add the assemblies for the controls in this file.

silverlight_controls_appmanifest_edited

We’re now ready to start developing an application. The xaml file for the first sample is a little bit too long to show here but feel free to download the code and have a look. Instead we’ll highlight the most important bits. For the xaml to work for the Button control we need to reference Microsoft.Silverlight.Controls and for the watermarked textbox we need Microsoft.Silverlight.Controls.Extended. We need to add reference to those in our app.xaml file by adding a namespace declaration of which the content looks like: clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls

silverlight_controls_references_in_xaml

We then added some controls to the app.xaml file as you can see in the download, but in mean time have a look at the live demo.  The ruby file that drives this xaml is very basic and only has 3 lines of code, all the code that is necessary to load the xaml file.

silverlight_controls_app_rb

Our next example will allow us to do something more useful like responding to a click event on a button. This demo is more ruby centric and uses a very small xaml file, without references to the assemblies containing the controls.

silverlight_controls2_xaml

Instead of adding the references in xaml we’re going to add them to our ruby file by using the ruby require statement.

silverlight_controls2_references_ruby

Yesterday we saw how we could use find_name to retrieve a control and manipulate it. Today I added the method missing implementation from the silverlight.rb file to the ruby file. This will give us the ability to write xaml.control_name instead of xaml.find_name(’control_name’)

silverlight_controls2_method_missing

The next part is adding some more controls to the canvas like a StackPanel that will contain a Button and a WatermarkedTextbox.   Tomorrow we’ll look at how we can pretty up that ruby code :) but for now we’re just going to use the standard api. We first create the instances of the controls and configure them. Next we add them to the panel and then we add the panel to the canvas.

silverlight_controls2_adding_controls

The last step for our mini application to actually respond to an action from the user is to handle the click event on the button. Ruby makes this as easy as assigning a block to the click attribute on the button instance.

silverlight_controls_handling_events

And that’s all for today. Tomorrow we’ll look at putting ruby to work for us and prettying up that api for adding elements to a silverlight control.

Technorati Tags: ,

del.icio.us Tags: ,

AddThis Social Bookmark Button

Silverlight minimal examples

April 14th, 2008 casualjim Posted in Silverlight, IronRuby 5 Comments »

I won’t be repeating the very basics of how to get started with silverlight here but will instead refer you to John Lam’s excellent blog post on the subject.  I do have to warn you for this series we won’t be using the silverlight.rb created by the dsl template generator.  I chose to do it this way so that you would better understand what is going on in the silverlight.rb file. I’ll assume from now on that you’re familiar with John’s post and move on.

Download the completed code

You can see the end result of these 2 examples in action:
http://flanders.co.nz/silverlight/minimal/index.html
http://flanders.co.nz/silverlight/minimal2/index.html

To run a silverlight website you don’t need a server side configuration. I’m hosting those examples on a linux box without mono installed. It’s just serving up files.

The first thing we need to do is create a skeleton for our application.

I did this by opening up Powershell (or the command prompt) and navigating to c:\projects\silverlight and executing the command dsl minimal_ir_project

image

Now that that’s done we’re going to delete silverlight.rb from the app folder. We can do that by going into that folder ( cd minimal_ir_project\app ) and executing del silverlight.rb Next we’re going to navigate one level up ( cd .. ) and start the webserver and default browser by executing chiron /b

image

At this point we’re entirely ready to start developing :) Let’s fire up an editor. For these examples I used notepad++ because Ruby In Steel has been acting up and it seemed a bit overkill to start up visual studio for the amount of coding we need to do in these 2 examples.

I first opened up the app.xaml file and gave it the following content.

app_xaml_rubydoes_net_minimal_sl1

This xaml ensures us that we will have a canvas container object and a TextBlock with name textblock. We’ve also set the font size of the text to 30 and if we don’t change the text through ruby it will read Hello world from XAML. To be able to show this xaml we need to edit the app.rb file and give it the following content:

include System::Windows
include System::Windows::Controls
Application.current.load_root_visual Canvas.new, “app.xaml”

The first 2 lines in that file are just like using statements in C# and provide access to the types living in those namespaces without having to fully qualify them. So instead of having to write System::Windows::Controls::Canvas you can use Canvas. And the next line tells our silverlight application that the visual root control has to be loaded as a Canvas type from the file app.xaml

If you switch now to your browser and click on the index.html file you will see Hello world from XAML in your browser. Very impressive, feel free to say woohoo ;) Let’s take it a little further and change the text of that text block to Hello world from IronRuby because after all it’s all about IronRuby.  To do that change the content from app.rb to:

app_rb_rubydoes_net_minimal_sl1

And the end result looks like this in Internet Explorer (Firefox 3 crashes with silverlight currently)

hello_world_ironruby

I think this would be the least amount of code you have to write to get going with silverlight development.

Let’s look at how that code would look when we don’t use xaml.

Let’s create a second project minimal_ir_project2 like before but now we delete both silverlight.rb and app.xml. The only file that is left now is app.rb Again you can start the webserver.

The content of app.rb should look like this:

app_rb_no_xaml_rubydoes_net_minimal_sl2

This ruby code has the same effect as the previous app.xaml. We first create a canvas object, next we create a TextBlock object and configure it’s properties. After that we add the textblock objects to the children collection of the canvas instance. And lastly we set the canvas object to be the root visual of our silverlight application. And all that hard work yields the following result:

hello_world_ironruby2

This concludes the first article in our series on Silverlight and IronRuby. Today we covered the very basics of silverlight development.

Technorati Tags: ,

del.icio.us Tags: ,

AddThis Social Bookmark Button

Getting started with Silverlight and IronRuby

April 12th, 2008 casualjim Posted in IronPython, Silverlight, IronRuby 2 Comments »

This is my first post on this site and I hope there will be many more to come :) I’m Ivan Porto Carrero and am currently writing a book on IronRuby for Manning. I decided to use this blog to post about IronRuby so that this site can become a really useful resource for people that want to get into IronRuby.

When the beta for Silverlight 2.0 was released it got support for IronRuby. I personally think that Silverlight and IronRuby is a winning team.  But when you come from normal web development or windows forms development it does have little bit of a learning curve because of XAML.
But once you get passed that learning curve it’s a pretty sweet technology to master :)

There are other people that have blogged about silverlight and IronRuby before, it might be a good idea to check them out as well.

The guys in the IronPython world have a bunch of samples that were created by Michael Foord. I thought it might be interesting to port those samples to IronRuby.

http://www.voidspace.org.uk/ironpython/silverlight/index.shtml

Over the next couple of days I’ll post those on this site. Tomorrow we’ll start with the basics of using silverlight and IronRuby to write applications.

 

AddThis Social Bookmark Button

IronRuby Mix08 Content

March 11th, 2008 Aaron Junod Posted in mix08, Silverlight, IronRuby No Comments »

This years Mix conference was a lot of fun, and added to the IronRuby story a bit. On the first day of the conference I was able to score an interview with Mr. John Lam himself, and meet John Messerly as well. It was a great pleasure to meet and talk with both Johns, and you can hear my interview here. Dave Laribee also interviewed John on his neat little streaming phone, you can see that video here.

On Thursday John Lam had a Ruby Ruby Ruby session where members of the IronRuby and DLR teams fielded questions from the community. You can see the video from this session here.

Friday, though, was the big event. John Lam and Jimmy Schementi gave their presentation where we got to see IronRuby, IronPython, and some c# all running in silverlight in the browser at the same time. They showed us Chiron, a web server built for silverlight development, and introduced us to dynamicsilverlight.net, the place where you can get all the tools they were showing off. The presentation was great fun, and I suggest you watch it here. John Lam also posted a deeper walkthrough of everything in the presentation in a three part series on his blog, part1, part2, part3.

My main take away, MS is very serious about Silverlight and IronRuby. I’m even more convinced of it after being at mix, and talking to MS and non-MS folks. I’ve also become a believer in Silverlight, I went to mix a skeptic, but was very impressed both with capability and matureness. It’s time to start learning Silverlight because, at least in my opinion, it’s going to be big.

AddThis Social Bookmark Button

Just Glue It! Ruby and the DLR in Silverlight from Remix Boston 07

October 10th, 2007 Aaron Junod Posted in dsl, remix07, Silverlight, IronRuby 1 Comment »

I spent Monday and Tuesday of this week at Remix07 Boston and had a great time. Like the original Mix conference, the Remix conference was mostly targeted at v-next web technologies, with a extremely heavy focus on Silverlight. When I first heard of Silverlight I was a skeptic, but the more I learn about it the more I see it will be a very compelling product.

One of the sessions I went to was Just Glue It, Ruby and the DLR in Silverlight by David Laribee. David did a great job explaining Domain Specific Languages, and showing off lots of the ALT.NET tools and practices. One thing that really gelled for me was how he explained the future proliferation of DSL’s into our industry. If you look at rails for example, there are at least 3 DSL’s jammed in there, one at each “tier”. David wanted to make the point that if we start creating lots and lots of small DSL’s to solve the multitude of problems in our domain, that our code will be cleaner, more maintainable, and more expressive.

David also showed off some Ruby, which I think many people in the room had very little experience or knowledge of. It’s hard to show how malleable Ruby is and the advantages that adds in an 1.5 hour session, but David did a good job showing some of the highlights of the language.

David did not have a chance to show off any IronRuby which was a shame, but increasing the general knowledge of the .net community serves much more purpose, at least until IronRuby is a little more baked.

AddThis Social Bookmark Button

Weekend update and links

July 30th, 2007 Aaron Junod Posted in Silverlight, Samples, IronRuby No Comments »

I spent the weekend trying to dive into Microsoft.Scripting, AKA the DLR, and between chasing my son and various trips to the store I was able to grok some of the framework. I hope to start posting more in depth content about how IronRuby is actually implemented on the DLR. I also spent some time with Silverlight and ended up throwing out a VM that was probably ok. A couple things I learned about silverlight over the weekend :

Don’t install 1.0 RC and 1.1 alpha, the 1.1 alpha is backwards compatible. (thanks Wilco).
The 1.0 SDK requires VS.net 2005, so don’t download it if you are trying to go Orcas only.
There were enough breaking changes between the past version and this version that not all silverlight pages may work right now if you’ve done the upgrade, so don’t throw out your VM because you can’t get Zero Gravity working :)
The DLR console is WAY cool.
Windows 2008 makes a perfectly good platform to development on once you turn on the “desktop experience” and turn off IE Enhanced Security.

Now the weekend links :
Mark (m2web) posts a Windows.Forms sample using Ironruby to create forms, and trap events.
A new IronRuby blog is up as well, and mentions IronMonkey, an effort to bring IronPython and IronRuby scripting to firefox.

AddThis Social Bookmark Button