2016-12-28 111 views
2

我有分頁查看用戶控件,它有自己的視圖模型。我在頁面中添加了一個分頁,其中的數據網格也有一個單獨的視圖模型。WPF MVVM分頁

我的問題是我怎麼可以更新的ObservableCollection我有我的頁面視圖模型的每一個命令,在我的分頁視圖模型做的時間?

這裏是我的PagingControl.xaml

<StackPanel Width="Auto" 
     Orientation="Horizontal"> 
     <Button     
      Margin="4,0" 
      Content="&lt;&lt;" 
      Command="{Binding FirstCommand}"/> 
     <Button 
      Margin="4,0" 
      Content="&lt;" 
      Command="{Binding PreviousCommand}"/> 
     <StackPanel 
      VerticalAlignment="Center" 
      Orientation="Horizontal"> 
      <TextBlock 
       Text="{Binding Start}"/> 
      <TextBlock 
       Text=" to "/> 
      <TextBlock 
       Text="{Binding End}"/> 
      <TextBlock 
       Text=" of "/> 
      <TextBlock 
       Text="{Binding TotalItems}"/> 
     </StackPanel> 
     <Button 
      Margin="4,0" 
      Content="&gt;" 
      Command="{Binding NextCommand}"/> 
     <Button 
      Margin="4,0" 
      Content="&gt;&gt;" 
      Command="{Binding LastCommand}"/> 
     <ComboBox Width="100" ItemsSource="{Binding ItemsPerPage}" SelectedValue="{Binding ItemCount}"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="SelectionChanged"> 
       <i:InvokeCommandAction Command="{Binding CountChangedCommand}"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </ComboBox> 
    </StackPanel> 

PagingViewModel.cs

public class PagingViewModel : ViewModelBase 
{ 
    private ObservableCollection<DataModel> _data; 

    private int start = 0; 
    private int itemCount = 10; 
    private int totalItems = 0; 
    private readonly List<int> count; 

    private ICommand _firstCommand; 
    private ICommand _previousCommand; 
    private ICommand _nextCommand; 
    private ICommand _lastCommand; 
    private ICommand _countchangedCommand; 

    public ObservableCollection<DataModel> Data 
    { 
     get { return _data; } 
     set 
     { 
      if (_data!= value) 
      { 
       _data= value; 
       OnPropertyChanged("Data"); 
      } 
     } 
    } 

    public PagingViewModel() 
    { 
     count = new List<int> { 10, 20, 30}; 
     RefreshData(); 
    } 

    public int Start { get { return start + 1; } } 

    public int End { get { return start + itemCount < totalItems ? start + itemCount : totalItems; } } 

    public int TotalItems { get { return totalItems; } } 

    public List<int> Count { get { return count; } } 

    public int ItemCount { get { return itemCount; } set { itemCount = value; OnPropertyChanged("ItemCount"); } } 

    public ICommand FirstCommand 
    { 
     get 
     { 
      if (_firstCommand == null) 
      { 
       _firstCommand = new RelayCommand 
       (
        param => 
        { 
         start = 0; 
         RefreshData(); 
        }, 
        param => 
        { 
         return start - itemCount >= 0 ? true : false; 
        } 
       ); 
      } 

      return _firstCommand; 
     } 
    } 

    public ICommand PreviousCommand 
    { 
     get 
     { 
      if (_previousCommand == null) 
      { 
       _previousCommand = new RelayCommand 
       (
        param => 
        { 
         start -= itemCount; 
         RefreshData(); 
        }, 
        param => 
        { 
         return start - itemCount >= 0 ? true : false; 
        } 
       ); 
      } 

      return _previousCommand; 
     } 
    } 

    public ICommand NextCommand 
    { 
     get 
     { 
      if (_nextCommand == null) 
      { 
       _nextCommand = new RelayCommand 
       (
        param => 
        { 
         start += itemCount; 
         RefreshData(); 
        }, 
        param => 
        { 
         return start + itemCount < totalItems ? true : false; 
        } 
       ); 
      } 

      return _nextCommand; 
     } 
    } 

    public ICommand LastCommand 
    { 
     get 
     { 
      if (_lastCommand == null) 
      { 
       _lastCommand = new RelayCommand 
       (
        param => 
        { 
         start = (totalItems/itemCount - 1) * itemCount; 
         start += totalItems % itemCount == 0 ? 0 : itemCount; 
         RefreshData(); 
        }, 
        param => 
        { 
         return start + itemCount < totalItems ? true : false; 
        } 
       ); 
      } 

      return _lastCommand; 
     } 
    } 

    public ICommand CountChangedCommand 
    { 
     get 
     { 
      if (_countchangedCommand == null) 
      { 
       _countchangedCommand = new RelayCommand 
       (
        param => 
        { 
         start = 0; 
         RefreshData(); 
        }, 
        param => 
        { 
         return ((totalItems - itemCount) > -10) ? true : false; 
        } 
       ); 
      } 

      return _countchangedCommand; 
     } 
    } 

    public void RefreshData() 
    { 
     _data= GetData(start, itemCount, out totalItems); 
DataViewModel vm = new DataViewModel(this); 

     OnPropertyChanged("Start"); 
     OnPropertyChanged("End"); 
     OnPropertyChanged("TotalItems"); 
    } 
} 

下面是我的頁面視圖模型:DataViewModel.cs

public class DataViewModel: ViewModelBase 
{ 
    private ObservableCollection<DataModel> _data; 

    public ObservableCollection<DataModel> Data 
    { 
     get { return _data; } 
     set 
     { 
      if (_data!= value) 
      { 
       _data= value; 
       OnPropertyChanged("Data"); 
      } 
     } 
    } 

    public DataViewModel(PagingViewModel pagevm) 
    { 
     _data = new ObservableCollection<DataModel>(); 
     _data= pagevm.Data; 
    } 

} 

我的數據屬性綁定到數據網格中的一個DataView.xaml用的ItemSource的DataContext設置爲DataViewModel。

回答

0

這是一個很好的相關詳細問題!

爲您刷新的問題,我看到幾個選項: 當RefreshData設置你數據你應該使用屬性的公共setter和不_data。如果你不這樣做,你將永遠不會使用OnPropertyChanged來通知視圖你的整個集合發生了變化。

所以你需要更換:

_data= GetData(start, itemCount, out totalItems); 

有了:

Data= GetData(start, itemCount, out totalItems); 

通過您的DataViewModel沒有意義的,我的方式。你_audits領域是無處可看和的ObservableCollection數據永遠不會在這個視圖模型設置。我相信你的問題必須來自這個問題。

PS:

在另一方面,我有一些建議不直接關係到你的問題:

首先,當你想檢查是否一些RelayCommand否則設置之前爲空你可能想使用?運營商:https://msdn.microsoft.com/en-us/en-en/library/ms173224.aspx

其次我高度建議您把您的RelayCommands行爲的方法。當你結束了命令打它是一個真正的混亂,以保持RelayCommand這裏的一切在lambda表達式發生。

這樣,您將替換此:

public ICommand NextCommand 
{ 
    get 
    { 
     if (_nextCommand == null) 
     { 
      _nextCommand = new RelayCommand 
      (
       param => 
       { 
        start += itemCount; 
        RefreshData(); 
       }, 
       param => 
       { 
        return start + itemCount < totalItems ? true : false; 
       } 
      ); 
     } 
      return _nextCommand; 
    } 
} 

有了這個:

public ICommand NextCommand 
{ 
    get 
    { 
     return _nextCommand = _nextCommand ?? new RelayCommand(Next, CanExecuteNext); 
    } 
} 

private void Next() 
{ 
    start += itemCount; 
    RefreshData(); 
} 

private bool CanExecuteNext() 
{ 
    return start + itemCount < totalItems ? true : false; 
} 
+0

喜炎yankelevich,是我不好的跟蹤線索的一部分。它應該是DataViewModel的構造函數,我已經編輯它並將嘗試你的答案。謝謝! :) –

+0

我實現了你的答案,但我的問題現在我似乎無法更新DataGrid中的數據是有界的。這些值已經通過,但datagrid沒有根據Observable Collection的新值更新:( –

0

這聽起來像你的命令需要能夠訪問你的網頁瀏覽模式。對於他們來說,你的分頁視圖模型需要保存對頁面視圖模型的引用(這樣你的分頁視圖模型可以把它傳遞給相關的命令)。

我建議使用屬性注入。在你的PagingViewModel中添加一個像這樣的屬性;

public AuditTrailViewModel AuditTrailViewModel { get; set; } 

(如果需要,請提供財產更改通知)。

在你的命令,你現在能夠訪問AuditTrailViewModel的性質

public ICommand LastCommand 
{ 
    get 
    { 
     if (_lastCommand == null) 
     { 
      _lastCommand = new RelayCommand 
      (
       param => 
       { 
        start = (totalItems/itemCount - 1) * itemCount; 
        start += totalItems % itemCount == 0 ? 0 : itemCount; 
        AuditTrailViewModel.Data = //Now you can update your viewModel 
        RefreshData(); 
       }, 
       param => 
       { 
        return start + itemCount < totalItems ? true : false; 
       } 
      ); 
     } 

     return _lastCommand; 
    } 
} 
+0

)嗨mark_h,我的AuditTrail部分是壞的。它應該是DataViewModel的構造函數,我已經編輯它,並會嘗試回答。謝謝!:) –

+0

嘗試過你的anser,並且在這一行給了我一個'OBject not set to instance'錯誤>> AuditTrailViewModel.Data = //現在你可以更新你的viewModel了。 –