1

MVVM模式在我的Silverlight4應用程序中實現。Silverlight:如何綁定列表<T>到數據網格

本來,我在我的ViewModel對象的ObservableCollection工作:

public class SquadViewModel : ViewModelBase<ISquadModel> 
{ 
    public SquadViewModel(...) : base(...) 
    { 
     SquadPlayers = new ObservableCollection<SquadPlayerViewModel>(); 
     ... 
     _model.DataReceivedEvent += _model_DataReceivedEvent; 
     _model.RequestData(...); 
    } 

    private void _model_DataReceivedEvent(ObservableCollection<TeamPlayerData> allReadyPlayers, ...) 
    { 
     foreach (TeamPlayerData tpd in allReadyPlayers) 
     { 
      SquadPlayerViewModel sp = new SquadPlayerViewModel(...); 
      SquadPlayers.Add(sp); 
     } 
    } 
    ... 
} 

這裏是XAML代碼電網peacie顯示:

xmlns:DataControls="clr-namespace:System.Windows.Controls; 
        assembly=System.Windows.Controls.Data" 
... 
<DataControls:DataGrid ItemsSource="{Binding SquadPlayers}"> 
    ...</DataControls:DataGrid> 

和我的視圖模型被綁定到DataContext屬性風景。

此集合(SquadPlayers)創建後沒有改變,所以我想它的類型改爲

List<SquadPlayerViewModel> 

。當我這樣做,我也在「_model_DataReceivedEvent」方法結束時加入

RaisePropertyChanged("SquadPlayers") 

(以通知列表數據被改變的網格。

的問題是,在初始顯示網格不顯示任何記錄...只有當我點擊任何列標題時,它會做'排序'並顯示列表中的所有項目...

問題1:爲什麼datagrid最初不包含項目? Q2:如何製作他們自動顯示?

謝謝。

P.S.這是新的列表對象在我的視圖模型聲明:

 public List<SquadPlayerViewModel> SquadPlayers { get; set; } 

回答

3

不能使用列表作爲綁定源,因爲名單沒有實現INotifyCollectionChanged它是要求WPF/Silverlight知道收集的內容是否更改。 WPF/Sivlerlight可以採取進一步行動。

我不知道你爲什麼需要列表<>在你的視圖模型上,但如果是抽象的原因,你可以使用IList <>。但請確保將ObservableCollection的實例放在它上面,而不是列表<>。無論您在ViewModel Binding Only中使用什麼類型都關心運行時類型。

所以你的代碼應該是這樣的:

//Your declaration 
public IList<SquadPlayerViewModel> SquadPlayers { get; set; } 
//in your implementation for WPF/Silverlight you should do 
SquadPlayers = new ObservableCollection<SquadPlayerViewModel>(); 
//but for other reason (for non WPF binding) you can do 
SquadPlayers = new List<SquadPlayerViewModel>(); 

我通常用這種辦法來抽象我的「已代理」的領域模型,通過NHibernate的返回。

+0

如果我正確理解,如果我想使用List <>作爲綁定目的,解決方法(RaisePropertyChanged(「SquadPlayers」);)將無濟於事。對? 謝謝。 – Budda 2010-08-24 11:56:38

+1

是和否,是的,如果您爲'SquadPlayers.Add(blah..blah)'分配了'SquadPlayers = blah .. blah..',但沒有。標記'RailsPropertyChanged(「SquadPlayers」)'收集'SquadPlayers'實例更改爲新的時候工作,但這還不夠,因爲收集需要通知天氣其項目已更改(添加或刪除)。 – ktutnik 2010-08-24 12:50:07

+0

有區別,...我看到的第一個問題:我通知集合發生了變化,但實際上集合是相同的,只有其中的項目發生了變化。今天我將嘗試替換集合(但我想,這將打破所有綁定)。所以我需要通知集合項目已更改...並且如果我正確理解 - 這對List <>是不可能的。我對嗎? – Budda 2010-08-25 19:47:47

1

的問題是,而PropertyChanged事件通知的價值實際上並沒有改變「變」的結合,集合對象是仍然是同一個對象。如果他們認爲價值沒有真正改變,一些控制措施可以爲自己節省一些不必要的工作。

嘗試創建ObservableCollection的新實例並指定給該屬性。在這種情況下,當前分配的對象將與數據可用時創建的新對象不同。

+0

將新列表添加到網格是一個好主意,同意...但我不明白我如何將ViewModel中的新列表綁定到網格(即來自View層的對象)。如果你能澄清這一點,我將不勝感激。謝謝。 – Budda 2010-08-15 00:30:25

2

你需要讓你的SquadPlayers列表定義是這樣的:


private ObservableCollection<SquadPlayerViewModel> _SquadPlayers;

public ObservableCollection<SquadPlayerViewModel> SquadPlayers 
    { 
     get 
     { 
      return _SquadPlayers; 
     } 

     set 
     { 
      if (_SquadPlayers== value) 
      { 
       return; 
      } 

      _SquadPlayers= value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged("SquadPlayers"); 
     } 
    } 

+0

嗨,邁克,在我原來的陳述中,我已經提到可觀察集合在初始化初始化後沒有改變。由於這個原因,我使用List <>替換了ObservableCollection <>。我沒有提到嗎? – Budda 2010-08-18 02:30:08

+0

這就是爲什麼我說「類似」。用列表替換ObservableCollection。這是我的一些工作代碼的一個片段,我只是改變了一些名稱以適合您的示例。 這一點主要是爲了確保列表完全定義爲屬性。這是在黑暗中拍攝的,因爲我不知道你是如何聲明或完全查看你的XAML的。 – Mike 2010-08-18 02:47:31

+0

邁克,謝謝你的時間。列表被聲明爲一個屬性,我已經將它添加到描述中。請讓我知道如果您有任何其他想法 – Budda 2010-08-24 02:17:31

相關問題