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

标签 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 没有看到该值已更新。我哪里错了?

最佳答案

好吧,我不熟悉 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,所以你一定要阅读它)可以在 IronPython 中实现 INotifyPropertyChanged。为此,您应该让您的 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")

关于python - 如何从 IronPython 更新 WPF DataGrid 一行的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30267353/

相关文章:

python:使用 socket.recv() 循环

python - 求和 Django 中的记录值

c# - 在 C# 中执行 WPF 元素验证?

python - CPython 和 IronPython cPickle 之间的兼容性

javascript - 用于抓取的服务器端脚本语言的替代方案

python - 谷歌应用程序引擎 urlfetch gzip 到字符串

C# - WPF - 防止更新绑定(bind)的焦点文本框

wpf - 如何设计一个在左侧或右侧显示行号的文本框?

visual-studio - 如何使用 IronPython 在 WPF 中使用相对图像源

python - 如何在python中的for循环中更改对象变量