2011-03-14 19 views
5

मैं एक WPF डेटा ग्रिड कि MVVM पी & पीMVVM पेजिंग और छँटाई

निम्न उदाहरण के अनुरूप है के लिए छंटाई और पेजिंग impletmenting के लिए पर्याप्त समाधान ढूँढने के साथ संघर्ष कर रहा हूँ पेजिंग जो MVVM इस प्रकार लागू करने के लिए एक प्रभावी तरीका दिखाता है प्रथाओं, लेकिन छँटाई के कस्टम कार्यान्वयन (जो एक बार आप पेजिंग को लागू की आवश्यकता है) MVVM का पालन नहीं करता:

http://www.eggheadcafe.com/tutorials/aspnet/8a2ea78b-f1e3-45b4-93ef-32b2d802ae17/wpf-datagrid-custom-pagin.aspx

मैं वर्तमान में है एक डेटा ग्रिड एक CollectionViewSource करने के लिए बाध्य (XAML में GroupDescriptions और SortDescritpt के साथ परिभाषित आयनों) मेरे व्यू मॉडेल में एक अवलोकन करने योग्य चयन के लिए बाध्य। जैसे ही आप पेजिंग को प्रति पृष्ठ प्राप्त करने वाले आइटमों की संख्या सीमित करके पेजिंग को कार्यान्वित करते हैं, यह संग्रहव्यूसोर्स में परिभाषित सॉर्टिंग को तोड़ देता है क्योंकि यह केवल आइटम्स का सबसेट सॉर्ट कर रहा है। पेजिंग और सॉर्टिंग को लागू करने के लिए एमवीवीएम के तहत सबसे अच्छा तरीका क्या है?

धन्यवाद,

हारून

उत्तर

12

दूसरे दिन मैं पृष्ठन के साथ मदद करने के लिए एक PagingController वर्ग लिखा था, इसलिए यहाँ तुम जाओ:

आप स्रोतों को साफ करने के लिए थोड़ा ख होगा ecause एमएस कोड संविदा के कुछ उपयोग आदि

प्रयोग नमूना (codebehind - ViewModel.cs) करते हैं, वे प्रिज्म से कुछ (वास्तव में बुनियादी) उपयोगिता सामान संदर्भ,:

private const int PageSize = 20; 

private static readonly SortDescription DefaultSortOrder = new SortDescription("Id", ListSortDirection.Ascending); 

private readonly ObservableCollection<Reservation> reservations = new ObservableCollection<Reservation>(); 

private readonly CollectionViewSource reservationsViewSource = new CollectionViewSource(); 

public ViewModel() 
{ 
    this.reservationsViewSource.Source = this.reservations; 

    var sortDescriptions = (INotifyCollectionChanged)this.reservationsViewSource.View.SortDescriptions; 
    sortDescriptions.CollectionChanged += this.OnSortOrderChanged; 

    // The 5000 here is the total number of reservations 
    this.Pager = new PagingController(5000, PageSize); 
    this.Pager.CurrentPageChanged += (s, e) => this.UpdateData(); 

    this.UpdateData(); 

} 

public PagingController Pager { get; private set; } 

public ICollectionView Reservations 
{ 
    get { return this.reservationsViewSource.View; } 
} 

private void UpdateData() 
{ 
    var currentSort = this.reservationsViewSource.View.SortDescriptions.DefaultIfEmpty(DefaultSortOrder).ToArray(); 

    // This is the "fetch the data" method, the implementation of which 
    // does not directly interest us for this example. 
    var data = this.crsService.GetReservations(this.Pager.CurrentPageStartIndex, this.Pager.PageSize, currentSort); 
    this.reservations.Clear(); 
    this.reservations.AddRange(data); 
} 

private void OnSortOrderChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    if (e.Action == NotifyCollectionChangedAction.Add) { 
     this.UpdateData(); 
    } 
} 

प्रयोग नमूना (XAML - View.xaml):

<DataGrid ... ItemSource="{Binding Reservations}" /> 

<!-- all the rest is UI to interact with the pager --> 
<StackPanel> 
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="4"> 
     <StackPanel.Resources> 
      <Style TargetType="{x:Type Button}"> 
       <Setter Property="FontFamily" Value="Webdings" /> 
       <Setter Property="Width" Value="60" /> 
       <Setter Property="Margin" Value="4,0,4,0" /> 
      </Style> 
      <Style TargetType="{x:Type TextBlock}"> 
       <Setter Property="Margin" Value="4,0,4,0" /> 
       <Setter Property="VerticalAlignment" Value="Center" /> 
      </Style> 
      <Style TargetType="{x:Type TextBox}"> 
       <Setter Property="Margin" Value="4,0,4,0" /> 
       <Setter Property="Width" Value="40" /> 
      </Style> 
     </StackPanel.Resources> 
     <Button Content="9" Command="{Binding Path=Pager.GotoFirstPageCommand}" /> 
     <Button Content="3" Command="{Binding Path=Pager.GotoPreviousPageCommand}" /> 
     <TextBlock Text="Page" /> 
     <TextBox Text="{Binding Path=Pager.CurrentPage, ValidatesOnExceptions=True}" /> 
     <TextBlock Text="{Binding Path=Pager.PageCount, StringFormat=of {0}}" /> 
     <Button Content="4" Command="{Binding Path=Pager.GotoNextPageCommand}" /> 
     <Button Content=":" Command="{Binding Path=Pager.GotoLastPageCommand}" /> 
    </StackPanel> 
    <ScrollBar Orientation="Horizontal" Minimum="1" Maximum="{Binding Path=Pager.PageCount}" Value="{Binding Path=Pager.CurrentPage}"/> 
</StackPanel> 

लघु विवरण:

जैसा कि आप देखते हैं, ViewModel वास्तव में बहुत कुछ नहीं करता है। यह वर्तमान पृष्ठ का प्रतिनिधित्व करने वाले आइटमों का संग्रह रखता है, और दृश्य में CollectionView (डेटा बाध्यकारी के लिए) और PagingController का खुलासा करता है। तो यह सब कुछ संग्रह में डेटा आइटम अपडेट करता है (और इसके परिणामस्वरूप CollectionView में) हर बार PagingController इंगित करता है कि कुछ बदल गया है। बेशक इसका मतलब है कि आपको एक विधि की आवश्यकता है, एक प्रारंभिक सूचकांक, एक पृष्ठ आकार, और SortDescription[] इन पैरामीटर द्वारा वर्णित डेटा का टुकड़ा देता है। यह आपके व्यापार तर्क का हिस्सा है, और मैंने इसके लिए कोड भी शामिल नहीं किया है।

एक्सएएमएल पक्ष पर सभी काम PagingController पर बाध्यकारी द्वारा किया जाता है।मैंने यहां पूर्ण कार्यक्षमता का खुलासा किया है (बटन पहले/पिछला/अगला/अंतिम आदेश, TextBox से CurrentPage पर बाध्यकारी, और ScrollBar से CurrentPage पर बाध्यकारी)। आम तौर पर आप एक ही समय में इन सभी का उपयोग नहीं करेंगे।

+0

धन्यवाद जॉन, बहुत सराहना की! – Aaron

+0

क्या यह डेटाग्रिड के लिए काम करेगा जो आकार बदलता है (और इस प्रकार दृश्य तत्वों की मात्रा को बदलता है? –

+0

@ChrisKlepeis: जैसा कि दिया गया है लेकिन आप 'पेजसाइज' से जुड़ सकते हैं और 'PropertyChanged'' के लिए साइन अप नहीं कर सकते हैं, इसलिए मुझे नहीं दिखाई देता वहाँ कोई शोस्टॉपर्स। बेशक पेजर इस मामले को कुशलतापूर्वक कवर करने के लिए नहीं था, इसलिए पेर्फ उतना अच्छा नहीं होगा जितना हो सकता है। – Jon

4

आप अपने ViewModel में टाइप ListCollectionView का एक संग्रह संपत्ति का उपयोग करना चाहिए, और यह करने के लिए ग्रिड बाँध। इस तरह संग्रहव्यू परिभाषा व्यू में नहीं बैठेगी बल्कि इसके बजाय व्यूमोडेल (जहां यह संबंधित है) में और इससे आपको उन सभी कुशलताओं को करने में मदद मिलेगी जिन्हें आप व्यूमोडेल में आसानी से चाहते हैं (चाहे वह पेजिंग, सॉर्टिंग या फ़िल्टरिंग हो)

+2

प्रतिक्रिया एलाड के लिए धन्यवाद! – Aaron

+1

यह एक अच्छा जवाब है। धन्यवाद! –

संबंधित मुद्दे