2015-05-15 2 views
7

У меня есть простое приложение WPF. Вот код WPFКак обновить значение строки WPF DataGrid от 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> 

и вот код питона:

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 не видит, что значение обновляется. Где я иду не так?

ответ

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++; 
    } 
} 

Теперь для Binding="{Binding value}" в XAML для работы , необходимо внести два изменения:

(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 (что, так как я не знаю, не питон вы обязательно должны прочитать его) можно реализовать 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")