2016-12-28 72 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了。 –