1

I've always enjoyed GUI development using XAML-based frameworks such as WPF, Xamarin.Forms, etc. In Python I've used PyQT and tkinter, but I really don't enjoy using either of them. I recently found out about Python.NET (http://pythonnet.github.io/), and I've been tinkering with building WPF/XAML-based apps using Python.

I have had some success, but I've also hit a lot of roadblocks. One roadblock I am trying overcome right now has to do with databinding, specifically using a DataTemplate that I've defined in the XAML. I am trying to populate a ListBox, and I've defined a DataTemplate for the items of the ListBox. Here is my XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="RePlay Database Builder: Select a database" 
        Height="600" 
        Width="800">

    <Grid>
        <ListBox Margin="20,10" Name="MyListBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>

                        <TextBlock Grid.Row="0" Grid.Column="0" Text="Name: " FontWeight="Bold" HorizontalAlignment="Left" />
                        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=MyName}" HorizontalAlignment="Left" />
                        <TextBlock Grid.Row="1" Grid.Column="0" Text="Path: " FontWeight="Bold" HorizontalAlignment="Left" />
                        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=MyPath" HorizontalAlignment="Left" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>

</Window> 

Now, I'd like to populate that listbox and have everything "link up" properly. Here's the current code I am attempting to use, but it's (obviously) not working:

import clr
clr.AddReference("wpf\PresentationFramework") 
clr.AddReference("System.Collections") 

from System.IO import *
from System.Windows.Markup import XamlReader
from System.Windows import *
from System.Threading import Thread, ThreadStart, ApartmentState
from System.Windows.Controls import *
from System.Collections.Generic import List
import System

class TestObject(System.Object):
    def __init__(self, my_name, my_path):
        self.MyName = my_name
        self.MyPath = my_path

class MyWindow(Window):
    def __init__(self):
        try:
            stream = StreamReader('MyWindow.xaml')
            self.window = XamlReader.Load(stream.BaseStream)

            self.test_list = List[TestObject]()
            self.test_list.Add(TestObject("Item1", "Path1"))
            self.test_list.Add(TestObject("Item2", "Path2"))
            self.test_list.Add(TestObject("Item3", "Path3"))

            MyListBox = LogicalTreeHelper.FindLogicalNode(self.window, "MyListBox")
            MyListBox.ItemsSource = self.test_list

            Application().Run(self.window)      
        except Exception as ex:
            print(ex)

if __name__ == '__main__':
    thread = Thread(ThreadStart(MyWindow))
    thread.SetApartmentState(ApartmentState.STA)
    thread.Start()
    thread.Join()

I was wondering if anyone could provide guidance on how to get DataTemplates working well in Python.NET. Thanks!

David
  • 1,847
  • 4
  • 26
  • 35
  • You realise data templates can be purely xaml? Or almost anyhow. I've no idea how you'd add an xmlns referencing a python class for datatype. I don't really follow why you'd want to use python with wpf though. – Andy Oct 19 '21 at 15:05
  • 1
    Pretty simple really: I haven't found a GUI framework in Python that I've enjoyed using. I've used PyQT and tkinter quite a bit, so it's not for a lack of trying. It's just that WPF and XAML-based GUI development is leaps-and-bounds better (and while I would normally use C# with WPF/XAML, this specific app needs to be done in Python). – David Oct 19 '21 at 15:09
  • You may want to take a look at IronPython, which is known to work with WPF. – Clemens Oct 19 '21 at 15:15
  • Yeah I have used IronPython in the past. I was hoping to use Python.NET since it is simply a package that can be imported rather than a separate interpreter entirely. I wanted to keep this app using the regular Python interpreter so it fits better with all the other non-gui code I have in the project already. – David Oct 19 '21 at 15:22
  • Have you found the solution, @David? – biluochun2010 Nov 02 '22 at 13:41

1 Answers1

2
  1. To make a Python class, that from the standpoint of .NET would behave like a .NET class you need __namespace__. E.g.
class TestObject(System.Object):
    __namespace__ = "MyApp.ViewModel"
    def __init__(self, my_name, my_path):
        super().__init__()
        self.MyName = my_name
        self.MyPath = my_path
  1. If that does not work you might want to try https://github.com/Alex141/CalcBinding
LOST
  • 2,956
  • 3
  • 25
  • 40