如何从IronPython更新WPF DataGrid行的值?

时间:2015-05-15 19:28:51

标签: python wpf ironpython

我有一个简单的WPF应用程序。这是WPF代码

<Window 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       Title="WpfApplication3" Height="300" Width="300"> 
       <Grid>
        <DataGrid x:Name="dg" Margin="0" Height="149" Width="136">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding value}" ClipboardContentBinding="{x:Null}"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="109,230,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
    </Grid>
</Window>

这是python代码:

import wpf

from System.Windows import Application, Window, MessageBox
from time import sleep

class MyWindow(Window):
    def __init__(self):
        self.value = Value()
        wpf.LoadComponent(self, 'WpfApplication3.xaml')

        self.dg.Items.Add(self.value)

    def button_Click(self, sender, e):
        self.value.increment()
        MessageBox.Show(str(self.value.value))

class Value:
    def __init__(self):
        self.value = 1

    def increment(self):
        self.value += 1

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

我期望的行为是,在单击按钮时,DataGrid中的值应该更新。当我启动应用程序时,一个条目在列中的值为1,但它不会在按钮单击时更新。 MessageBox确认正在更新该值,但DataGrid未看到该值已更新。我哪里错了?

1 个答案:

答案 0 :(得分:2)

好的,我不熟悉Python,所以如果我错了,请纠正我,但我认为你的代码在C#中看起来像这样:

public partial class MainWindow : Window
{
    public Value value;
    public MainWindow()
    {
        InitializeComponent();
        value = new Value();
        dg.Items.Add(value);
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        value.Increament();
        MessageBox.Show(Convert.ToString(value.value));
    }
}

public class Value 
{
    public int value;
    public Value()
    {
        value = 1;
    }
    public void Increament()
    {
        value++;
    }
}

现在,要使XAML中的Binding="{Binding value}"起作用,必须进行两项更改:

(1)必须设置DataContext。这可以很容易地完成如下:

import wpf

from System.Windows import Application, Window, MessageBox
from time import sleep

class MyWindow(Window):
    def __init__(self):
        self.value = Value()
        wpf.LoadComponent(self, 'WpfApplication3.xamll')

        self.dg.DataContext = self
        self.dg.Items.Add(self.value)

    def button_Click(self, sender, e):
        self.value.increment()
        MessageBox.Show(str(self.value.value))

(2) Value类必须实现INotifyPropertyChanged。因此,以下是在C#中正确实现此类:

public class Value : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    int _value;
    public int value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value; OnPropertyChanged("value");
        }
    }
    public Value()
    {
        value = 1;
    }
    public void Increament()
    {
        value++;
    }
}

根据我的理解阅读此Blog(由于我不知道没有python你应该阅读它)。可以在INotifyPropertyChanged中实现IronPython。为此,您应该让Value类实现INotifyPropertyChanged

from System.ComponentModel import INotifyPropertyChanged
from System.ComponentModel import PropertyChangedEventArgs

class Value(INotifyPropertyChanged):
    def __init__(self):
        self.propertyChangedHandlers = []
        self.value= 1

    def RaisePropertyChanged(self, propertyName):
        args = PropertyChangedEventArgs(propertyName)
        for handler in self.propertyChangedHandlers:
            handler(self, args)

    def add_PropertyChanged(self, handler):
        self.propertyChangedHandlers.append(handler)

    def remove_PropertyChanged(self, handler):
        self.propertyChangedHandlers.remove(handler)


    def Increament(self):
        self.value += 1
        self.RaisePropertyChanged("value")