2015-05-15 14 views
7

Ho una semplice applicazione WPF. Ecco il codice di WPFCome aggiornare il valore di una riga di WPF DataGrid da IronPython?

<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> 

e qui è il codice 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()) 

Il comportamento che mi aspetto è che il pulsante di clic, il valore nel DataGrid dovrebbe aggiornare. Quando avvio l'applicazione, una voce è posizionata nella colonna con il valore 1, ma non si aggiorna sul clic del pulsante. MessageBox conferma che il valore è in fase di aggiornamento, ma DataGrid non sta visualizzando il valore aggiornato. Dove sto andando male?

risposta

2

Ok, io non sono a conoscenza di Python così mi corregga se sbaglio, ma credo che il codice sarà simile a qualcosa di simile in 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++; 
    } 
} 

Ora, per Binding="{Binding value}" in XAML per lavorare , è necessario apportare due modifiche:

(1) È necessario impostare DataContext. Questo può essere fatto facilmente come segue:

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) La classe Value deve implementare INotifyPropertyChanged. Pertanto ciò che segue è la corretta applicazione di questa classe in 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++; 
    } 
} 

Da quello che ho capito leggendo questo Blog (che dato che non conosco nessuno di pitone si dovrebbe assolutamente leggerlo) E 'possibile implementare INotifyPropertyChanged in IronPython. Per ottenere ciò, è necessario lasciare gli strumenti della classe ValueINotifyPropertyChanged:

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")