2012-09-08 16 views
6

Ho riscontrato un problema durante l'aggiornamento del mio datagrid quando si fa clic sul pulsante utilizzando NotifyPropertyChanged. Funziona se imposto il DataGrid.ItemsSource nel codice, ma non lo fa se lo metto in xaml. ecco qualche codice di codice dietro & XAML:WPF DataGrid non si aggiorna su PropertyChanged

namespace MyWpfDataBindingLab 
{ 
public partial class NpcWindow : Window 
{ 
    DataCollection dc = new DataCollection(); 

    public NpcWindow() 
    { 
     InitializeComponent(); 
     //command binding code 
     //... 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     //if i set the ItemsSource here, updating of the UI works 
     //dataGrid1.ItemsSource = dc; 
    } 

    private void CmdCollectionChangedExecute(object sender, ExecutedRoutedEventArgs e) 
    { 
     foreach (SampleClass s in dc) 
     { 
      s.Property1 = "changed"; 
      s.Property3 = "changed"; 
      s.Property3 = "changed"; 
      break; 
     } 

     dc.Add(new SampleClass("new sample 1", "new sample 2", "new sample 3")); 
    } 
} 
} 

<Window x:Class="WPFDataBinding.NpcWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:npc="clr-namespace:WPFDataBinding.NotifyPropChanged" 
    Title="MainWindow" Height="189" Width="459" Loaded="Window_Loaded"> 
<Window.Resources> 
    <npc:DataCollection x:Key="dataCol"/> 
</Window.Resources> 
<Grid> 
    <Grid.ColumnDefinitions> 
    </Grid.ColumnDefinitions> 
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="349,110,0,0" Name="button1" VerticalAlignment="Top" Width="75" /> 
    <!-- if i set the ItemsSource here, updating of the UI doesn't work --> 
    <DataGrid ItemsSource="{Binding Source={StaticResource dataCol}, Mode=OneWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
       AutoGenerateColumns="True" Height="103" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="331" /> 
</Grid> 

miei dati & NotifyPropertyChanged implementazione:

namespace MyWpfDataBindingLab.NotifyPropChanged 
{  
public class SampleClass : NotifyPropertyChanged 
{ 
    private string _field1; 
    private string _field2; 
    private string _field3; 

    public string Property1 
    { 
     get { return _field1; } 
     set 
     { 
      _field1 = value; 
      OnPropertyChanged("Property1"); 
     } 
    } 

    public string Property2 
    { 
     get { return _field2; } 
     set 
     { 
      _field2 = value; 
      OnPropertyChanged("Property2"); 
     } 
    } 

    public string Property3 
    { 
     get { return _field3; } 
     set 
     { 
      _field3 = value; 
      OnPropertyChanged("Property3"); 
     } 
    } 

    public SampleClass() 
    { 
     _field1 = "value1"; 
     _field2 = "value2"; 
     _field3 = "value3"; 
    } 

    public SampleClass(string p1, string p2, string p3) 
    { 
     _field1 = p1; 
     _field2 = p2; 
     _field3 = p3; 
    } 
} 
} 

namespace MyWpfDataBindingLab.NotifyPropChanged 
{ 
public abstract class NotifyPropertyChanged : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
} 

namespace MyWpfDataBindingLab.NotifyPropChanged 
{ 
public class DataCollection : ObservableCollection<SampleClass> 
{ 
    public DataCollection() 
    { 
     this.Add(new SampleClass()); 
     this.Add(new SampleClass()); 
     this.Add(new SampleClass()); 
    } 
} 
} 

non ho idea di quale sia il problema. lo apprezzerei se qualcuno potesse aiutarti a risolvere il mio problema.

+0

Avete qualche codice che aggiunge effettivamente elementi all'istanza di 'DataCollection'? Se non aggiungi nulla, il gestore 'CmdCollectionChangedExecute' non si avvia. – slugster

+0

la raccolta viene aggiornata tramite CmdCollectionChangedExecute quando si fa clic sul pulsante. il nome del metodo è un po 'confuso. dovrebbe essere CmdCollectionChangeExecute. l'aggiornamento funziona bene, ma l'interfaccia utente si sta solo aggiornando se si imposta l'origine articoli nel codice. mi piace farlo solo nel file xaml. – nllpntr

risposta

9

Nei tuoi .xaml.cs codebehind creare proprietà

public ObservableCollection<SampleClass> MyCollection {get; set;} 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
    //if i set the ItemsSource here, updating of the UI works 
     dataGrid1.ItemsSource = MyCollection; 
    } 

In XAML:

<DataGrid ItemsSource="{Binding Path=., Mode=OneWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"/> 
+0

grazie per la rapida risposta. il tuo codice funziona bene. è possibile sbarazzarsi di dataGrid1.ItemsSource = MyCollection; nel codice dietro, e fare il binding completo in xaml? – nllpntr

+0

Puoi usare this.DataContext = MyCollection; – syned

+0

Grazie! Questo è proprio quello che stavo cercando - risolto il mio problema abbastanza bene. – Fred

7

Ho seguito il suggerimento di syned. Per quanto mi riguarda ho avuto a noi il modo come

Mode=TwoWay 

La chiave qui era di proprietà

UpdateSourceTrigger 

.

Grazie mille ...!