[IronPython] overriding methods from C# classes

Dino Viehland dinov at microsoft.com
Fri Jul 9 19:17:39 CEST 2010


Marcin wrote:
> Hello Michael and everyone,
> 
> Michael Foord wrote:
> > I recommend using the Visual Studio C# designer and then subclass
> > the classes it generates from IronPython.
> 
> I set out to do just that and stumbled upon a problem:
> 
> I generated Windows form in C#, compiled into assembly (ip_cl1), copied
> to python project folder:
> 
> clr.AddReference('ip_cl1')
> ..
> from ip_cl1 import Form1
> 
> 
> class Form1Inh(Form1):
>         def __init__(self):
>             Form1.__init__(self)
> 
>         def comboBox1_SelectedIndexChanged(self, sender, event):
>             self.BackColor = Color.Azure
> 
> This doesn't work, i.e. method comboBox1_SelectedIndexChanged doesn't
> get called. I have to expicitly add EventHandler in Python:
> 
> class Form1Inh(Form1):
>         def __init__(self):
>             Form1.__init__(self)
>             self.box1.SelectedIndexChanged +=
> EventHandler(self.comboBox1_SelectedIndexChanged);
> 
>         def comboBox1_SelectedIndexChanged(self, sender, event):
>             self.BackColor = Color.Azure
> 
> 
> Is there some way of simply overriding methods in Python so that they do
> get called by form events?

In both of these cases there are no methods to be overridden.  You're just 
defining methods which you want to use for the event handlers.  You need
to connect those methods to the event handlers somewhere.  Your C# code is
working probably because the connection of the event handlers is in the 
generated code in InitializeComponent().

This is one of the reasons why I suggest WPF over WinForms.  In WPF you can
declare the event handlers in the XAML and we can wire them up to you.  In
our IronPython 2.7 source code I recently added a clr.LoadComponent method which
does this.  So for WPF the code ends up looking like:

import clr
clr.AddReference('PresentationFramework')

from System.Windows import Application, Window

class MyWindow(Window):
    def __init__(self):
        clr.LoadComponent('WpfApplication16.xaml', self)
    
    def Button_Click(self, sender, e):
        pass

    

if __name__ == '__main__':
	Application().Run(MyWindow())


While the XAML looks like:

<Window 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       Title="WpfApplication16" Height="300" Width="300"> 
       <Grid>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="152,116,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" x:Name='Foo' />
    </Grid>
</Window>


And we'll both connect MyWindow.ButtonClick() to the event handlers as well as make Foo (the name of the button) available on the self instance.

WinForms is likely to always be a bit of a rough experience because we don't have the meta-data to know how to wire things up automatically for you.

> 
> 
> 
> 
> In Form1.cs I have:
> 
> 
> namespace ip_cl1
> {
>      public partial class Form1 : Form
>      {
>          public Form1()
>          {
>              InitializeComponent();
>          }
> 
>          protected void box1_SelectedIndexChanged(object sender,
> EventArgs e)
>          {
> 
>          }
> 
>          protected void comboBox1_SelectedIndexChanged(object sender,
> EventArgs e)
>          {
> 
>          }
>      }
> }
> 
> --
> 
> Regards,
> mk
> 
> --
> Premature optimization is the root of all fun.
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list