2012-10-30 66 views
3

我設計了一個MVVM WPF應用程序,並有一個ViewModel,它具有一個Customer類型的SelectedCustomer屬性。這個對象有一個叫做SummaryDetails的屬性,它的類型爲ObservableCollection,它可以一行一行地渲染成一個ListView。WPF MVVM可觀察集合不更新GUI

爲此,我在ViewModel上創建了一個名爲CustomerSummaryDetails的單獨屬性,它包含一個get,它返回包含在我上面提到的客戶中的集合。

在XAML中,我已將ItemsSource綁定到CustomerSummaryDetails屬性。

這是因爲我沒有必要綁定到SelectedCustomer.SummaryDetails是不乾淨。

SelectedCustomer屬性有一個get和一個set方法,並且該集合爲OTHER屬性CustomerSummaryDetails調用OnPropertyChanged,讓XAML知道底層集合已更改和更新。

雖然所有正確的事件被調用,但問題是,當我更新集合中的項目時,它不反映在GUI上。我已經介入並調用SelectedCustomer的set方法,然後按照預期的方式跟隨OnPropertyChanged(「CustomerSummaryDetails」)調用進入CustomerSummaryDetails屬性的「get」方法。我已經深入研究了返回集合的值,並且列表中的值是已更新的值,但是沒有任何結果反映在GUI上,所以我感到困惑,因爲看起來GUI正在調用get方法來更新它在OnPropertyChanged()調用上,但它不是可視化的反映。

更新 - 代碼中包含了

對不起,不包括代碼,我認爲這將是容易只是形容,但這裏是主要的視圖模型性能

public CustomerSummaryViewModel SelectedCustomer 
{ 
    get { return _selectedCustomer; } 
    set 
    { 
     _selectedCustomer = value; 
     OnPropertyChanged("CustomerSummaryDetails"); 
    } 
} 

public ObservableCollection<RbcUICustomerSummary> CustomerSummaryDetails 
{ 
    get { return _selectedCustomer.SummaryDetails; } 
} 

public ItemSummaryViewModel SelectedItem 
{ 
    get { return _selectedItem; } 
    set 
    { 
     _selectedItem = value; 
     OnPropertyChanged("SelectedItem"); 
    } 
} 

XAML下面

<ListView x:Name="lvCustomerSummary" Margin="10,10,10,10" Background="#F4F8FB" ItemsSource="{Binding CustomerSummaryDetails}" MouseDoubleClick="lvCustomerSummary_MouseDoubleClick" ItemContainerStyle="{StaticResource myHeaderStyleColor}" VirtualizingStackPanel.IsVirtualizing="False" VirtualizingStackPanel.VirtualizationMode="Recycling"> 
      <ListView.View> 
      <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}"> 
        <GridView.Columns> 
        <GridViewColumn Header="" > 
         <GridViewColumn.CellTemplate> 
          <DataTemplate > 
           <Grid> 
            <Image Source="{z:ImageStaticResource {Binding IconSelect}}" Width="20" Height="20" /> 
           </Grid> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Width="200" Header="SubCustType" DisplayMemberBinding="{Binding SubCustType}" > 
        </GridViewColumn> 
        <GridViewColumn Width="200" Header="SubCustValue" DisplayMemberBinding="{Binding SubCustValue}"> 
        </GridViewColumn> 
        <GridViewColumn Header="" > 
         <GridViewColumn.CellTemplate> 
          <DataTemplate > 
           <Grid> 
            <Image Source="{z:ImageStaticResource {Binding IconFlag}}" Width="20" Height="20" /> 
           </Grid> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       </GridView.Columns> 
      </GridView> 
     </ListView.View> 
    </ListView> 

最後是實際更新的更新器方法

private void DisplayCustomerComment(string commentEnt) 
{    
    if (_queueViewModel.SelectedCustomer == null) return; 
     var selCust = _queueViewModel.SelectedCustomer; 

    foreach (var t in selCust.SummaryDetails 
     .Where(t => t.SubCustType == AppString.CustomerSummary.Comment)) 
    { 
     t.SubCustValue = commentEnt; 
     break; 
    } 

    _queueViewModel.SelectedCustomer = selCust; 
} 
+0

雖然你說類型「客戶」,什麼樣的數據類型是「客戶」...它是一個強類型的類對象,數據表的數據行等? – DRapp

+0

您的CustomerSummaryDetails屬性的簽名是什麼?我建議發佈一些源代碼而不是描述它可能也更容易。 :-) – AlSki

+0

您的綁定模式設置爲? –

回答

16

您並未修改ObservableCollection本身(如添加/刪除項目),而是修改了INSIDE集合中的項目。 ObservableCollection負責通知其自己的更改,而不是與其項目相關的更改。您應該在SubCustValue的設置器中通知屬性更改(「SubCustValue」)。

更改沒有反映在UI中,因爲當您NotifyPropertyChange()整個集合而不是單個項目的個別屬性時,WPF會檢測到它實際上是同一個實例(對同一個集合的同一對象引用)像以前一樣,所以沒有任何改變。

+0

作爲一個便箋,爲什麼你要收集第一個項目並破解?替換FirstOrDefault()或其他東西並刪除foreach。 –

+0

你能否解釋一下,如果我在裏面有簡單的集合(沒有可觀察的),我怎樣才能更新\ rebind數據。哪種方式最好?謝謝。 –

+0

@СергійКислий這是一個單獨的問題,你寧願發表一個新的問題。 –