2014-04-04 156 views
1

這是我第一次使用WPF,MVVM和Entity framework 6 Code First。它是一個簡單的小額貸款模擬器,由左面板組成,其中包含貸方參數和右側面板中的數據網格,刷新參數中所做的每個更改,其中包含實體「Echeance」的集合。因此,左面板包含Textboxes數據綁定到「模擬」實體中的屬性,並將數據網格數據綁定到ObservableCollection。WPF和MVVM:如何刷新控件

問題是,當我更改任何參數時,datagrid不會刷新更改。

在我使用MVVM之前,應用程序工作正常。 代碼如下:

//Entity Echeance 
public partial class Echeance : INotifyPropertyChanged 
{ 
    public long echeanceId { get; set; } 
    public byte echNumber { get; set; } 
    public double principal; 
    .... //Other fields 
    ... 
    //Navigation to the parent 

    public virtual simulation simulation { get; set; } 


//Contructor with Echeance Number 
    Echeance(byte n) 
{ 
echNumber = n; 
} 

... 


    public double MontantPrincipal 
    { 
     get 
     { 
      return principal; 
     } 

     set 
     { 
      principal = value; 
      OnPropertyChanged("MontantPrincipal"); 
     } 
    } 

...Other properties 
.... 
// 
public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 

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

} 



//Entity simulation 
    public partial class simulation 
{ 

     public long simulationId { get; set; } 
     ... 
     public double loyer { get; set; } 

     public virtual IList<Echeance> echeancier { get; set; } 
} 

視圖模型如下:

public class VMSimulation : ObservableObject 
{ 
#region Fields 
    simulation _simulation; 
    ...   
    ObservableCollection<Echeance> _echeancier; 
#endregion 


    #region Constructeur 
    public VMSimulation() 
    { 
     _simulation = new simulation(); 
     _echeancier = new ObservableCollection<Echeance>(_simulation.echeancier); 
     // LogIt(); 
    } 
    #endregion 

    #region Properties 

    public ObservableCollection<Echeance> Echeancier 
    { 
     get 
     { 
      return _echeancier; 
     } 

     set 
     { 
      _echeancier = value; 
      OnPropertyChanged("Echeancier"); 
     } 
    } 

.... 
    public double Loyer 
    { 
     get { return _simulation.loyer; } 
     set 
     { 
      _simulation.loyer = value; 
      OnPropertyChanged("Loyer"); 
     } 
    } 
... 
} 

XAML只是場在那裏我有刷新麻煩

<viblend:NumberEditor x:Name="txloy"  
            Value="{Binding Path=Loyer, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" 
            Grid.Column="7" Grid.Row="2" 
            Style="{StaticResource viBlendDecimal}" Width="72" ToolTip="Loyer computed." IsEnabled="False" /> 


<DataGrid x:Name="gridLoyers" ItemsSource="{Binding Echeancier}" 
        AutoGenerateColumns="False" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Margin="0" 
       Grid.Column="0" Grid.Row="1" CellEditEnding="gridLoyers_CellEditEnding_1" > 
       <DataGrid.Columns> 
        <DataGridTextColumn Binding="{Binding NumLoy, Mode=TwoWay, StringFormat='{}{0:#}'}" ElementStyle="{StaticResource DataGridCellRightAlignment}"  Header="N°" /> 
        <DataGridTextColumn Binding="{Binding DateEcheance ,  StringFormat={}\{0:dd/MM/yyyy\}, Mode=TwoWay}"  ElementStyle="{StaticResource DataGridCellCenterAlignment}" Header="Echéance"/> 
        <DataGridTextColumn Binding="{Binding MontantPrincipal, StringFormat='{}{0:#.##,0}',UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  ElementStyle="{StaticResource DataGridCellRightAlignment}" Header="Principal" /> 
        <DataGridTextColumn Binding="{Binding MontantInteret, StringFormat='{}{0:#.##,0}'}"  ElementStyle="{StaticResource DataGridCellRightAlignment}" Header="Intérêts"/> 
        <DataGridTextColumn Binding="{Binding MontantHT, StringFormat='{}{0:#.##,0}', UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  ElementStyle="{StaticResource DataGridCellRightAlignment}" Header="Hors taxe" /> 
        <DataGridTextColumn Binding="{Binding MontantTVA, StringFormat='{}{0:#.##,0}'}"  ElementStyle="{StaticResource DataGridCellRightAlignment}" Header="TVA"/> 
        <DataGridTextColumn Binding="{Binding MontantTTC, StringFormat='{}{0:#.##,0}'}"  ElementStyle="{StaticResource DataGridCellRightAlignment}"  Header="TTC"/> 
        <DataGridTextColumn Binding="{Binding Amortfin, StringFormat='{}{0:#.##,0}'}"  ElementStyle="{StaticResource DataGridCellRightAlignment}"  Header="Amortissement"/> 
        <DataGridTextColumn Binding="{Binding Encours, StringFormat='{}{0:#.##,0}'}"   ElementStyle="{StaticResource DataGridCellRightAlignment}"  Header="Encours financier"/> 
        <DataGridCheckBoxColumn Binding="{Binding Fixe, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"   ElementStyle="{StaticResource DataGridCellRightAlignment}"  Header="Figé ?"/> 
       </DataGrid.Columns> 
      </DataGrid> 

最後的觀點:

//Constructeur de la fenêtre 
    public simulationform() 
    { 
     InitializeComponent(); 
     VMSimulation vms = new VMSimulation(); //Instanciation du ViewModel Associé 
     this.DataContext = vms; 
     vms.ClosingRequest += (sender, e) => this.Close(); 
    } 

datagrid不會刷新ObservableCollection並且不會刷新「Loyer」屬性。我調試這個,我發現「命令」工作正常,列表包含正確的數據,但它不刷新。 當我點擊任何列標題時,datagrid中的數據將被正確刷新。奇怪的行爲 !!!

在此先感謝

+0

對於UI控件來更新視圖模型,視圖模型*和*數據對象的類必須實現'INotifyPropertyChanged'界面所做的更改。看起來您已經完成了這項工作,但我無法確定您的實施是否有效。 – Sheridan

+0

嘗試'ItemsSource =「{綁定Echeancier,UpdateSourceTrigger = PropertyChanged}」'看看是否有幫助。 – XAMlMAX

+0

我試過了......還是一樣的問題。 –

回答

0

對不起,在視圖模型的命令代碼丟失。

public ICommand RefreshCommand 
    { 
     get 
     { 
      if (_refreshCommand == null) 
       _refreshCommand = new DelegateCommand<object>(RefreshCommandExecute); 
      return _refreshCommand; 
     } 
    } 



void RefreshCommandExecute(object obj) 
    { 
     _simulation.RefreshEcheancier(); 
     //I added this line and it works fine 
     Echeancier = new ObservableCollection<Echeance>(_simulation.echeancier); 
    } 

所以我最近添加一行:

Echeancier = new ObservableCollection<Echeance>(_simulation.echeancier); 

和DataGrid刷新工作正常。

謝謝...

0

通過將該值設置到現場你繞過你的屬性設置與INotifyPropertyChange觸發沿,所以在構造函數做你的值設置爲屬性不是字段。

Codewise如果你的虛擬機的構造:

#region Constructeur 
    public VMSimulation() 
    { 
     _simulation = new simulation(); 
     Echeancier = new ObservableCollection<Echeance>(_simulation.echeancier); // instead of _echeancier = ... 
     // LogIt(); 
    } 
    #endregion 
+0

你能澄清一點嗎?你的意思是我必須從INotifyPropertyChanged繼承仿真嗎? –

+0

通過設置值來繞過Echeancier屬性設置器,因此OnPropertyChanged(「Echeancier」);永遠不會被調用,虛擬機沒有機會報告變化。 – user3455395

+0

user3455395:我寫得正確。請查看我上面的代碼。我寫道:_echeancier = new ObservableCollection (_simulation.echeancier);不是Echeancier =新的ObservableCollection (_simulation。echeancier); –