ठीक है, तो यह सवाल विंडोज फोन 7/सिल्वरलाइट (अद्यतन WP7 टूल्स, सितंबर 2010) से संबंधित है, विशेष रूप से अंतर्निहित ObservableCollection<T>
फ़िल्टरिंग।संग्रह दृश्य दृश्य पर स्वचालित रूप से फ़िल्टर और/या क्रमबद्ध क्रम को कैसे अपडेट करें, जब कोई व्यक्तिगत आइटम की संपत्ति बदलती है?
WP7 टेम्पलेट पिवोट कंट्रोल एप्लिकेशन के साथ मिलकर, मैंने एक समस्या में भाग लिया है जिससे ObservableCollection<T>
में अंतर्निहित आइटम को बदलना, परिणामस्वरूप ऑन-स्क्रीन ListBox को अपडेट किया जा रहा है। असल में, नमूना ऐप में दो पिवट होते हैं, जो सीधे अंतर्निहित ObservableCollection<T>
से बंधे होते हैं, और दूसरा CollectionViewSource
(यानी अंतर्निहित ObservableCollection<T>
पर फ़िल्टर किए गए दृश्य का प्रतिनिधित्व करता है)।
अंतर्निहित आइटम कि ObservableCollection<T>
जोड़े जा रहे हैं INotifyPropertyChanged
लागू, जैसे इतना:
public class ItemViewModel : INotifyPropertyChanged
{
public string LineOne
{
get { return _lineOne; }
set
{
if (value != _lineOne)
{
_lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
} private string _lineOne;
public string LineTwo
{
get { return _lineTwo; }
set
{
if (value != _lineTwo)
{
_lineTwo = value;
NotifyPropertyChanged("LineTwo");
}
}
} private string _lineTwo;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != _isSelected)
{
_isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
} private bool _isSelected = false;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
फिर, मुख्य वर्ग में, एक डाटा संग्रह गढ़ी गई है (संक्षिप्तता के लिए कम सूची, यह भी ध्यान दें कि अन्य के विपरीत आइटम, LoadData के तीन() प्रविष्टियों IsSelected है == सच):
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
public ObservableCollection<ItemViewModel> Items { get; private set; }
public bool IsDataLoaded
{
get;
private set;
}
public void LoadData()
{
this.Items.Add(new ItemViewModel() { LineOne = "runtime one", IsSelected = true, LineTwo = "Maecenas praesent accumsan bibendum" });
this.Items.Add(new ItemViewModel() { LineOne = "runtime two", LineTwo = "Dictumst eleifend facilisi faucibus" });
this.Items.Add(new ItemViewModel() { LineOne = "runtime three", IsSelected = true, LineTwo = "Habitant inceptos interdum lobortis" });
this.Items.Add(new ItemViewModel() { LineOne = "runtime four", LineTwo = "Nascetur pharetra placerat pulvinar" });
this.Items.Add(new ItemViewModel() { LineOne = "runtime five", IsSelected = true, LineTwo = "Maecenas praesent accumsan bibendum" });
this.Items.Add(new ItemViewModel() { LineOne = "runtime six", LineTwo = "Dictumst eleifend facilisi faucibus" });
this.IsDataLoaded = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String propertyName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainPage.xaml फ़ाइल में, पहली धुरी अपने ItemSource
ObservableCollection<T>
सूची पर सीधे आधारित है। दूसरे पिवोट के भीतर, ऑन-स्क्रीन लिस्टबॉक्स में इसकी ItemSource
संपत्ति CollectionViewSource
पर सेट है, जिसका अंतर्निहित स्रोत ऊपर में ObservableCollection<T>
पर आधारित है।
<phone:PhoneApplicationPage.Resources>
<CollectionViewSource x:Key="IsSelectedCollectionView" Filter="CollectionViewSource_SelectedListFilter">
</CollectionViewSource>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="MY APPLICATION">
<!--Pivot item one-->
<controls:PivotItem Header="first">
<!--Double line list with text wrapping-->
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
<!--Pivot item two-->
<controls:PivotItem Header="second">
<!--Triple line list no text wrapping-->
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" ItemsSource="{Binding Source={StaticResource IsSelectedCollectionView}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineThree}" TextWrapping="NoWrap" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
</controls:Pivot>
</Grid>
<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1" Click="ApplicationBarIconButton_Click"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="MenuItem 1"/>
<shell:ApplicationBarMenuItem Text="MenuItem 2"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
ध्यान दें कि MainPage.xaml.cs में, Resources
खंड में CollectionViewSource
पर Filter
विशेषता के ऊपर एक फिल्टर हैंडलर, जो उन वस्तुओं है कि है IsSelected
के माध्यम से sifts असाइन किया गया है सत्य पर सेट करें:
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
CollectionViewSource isSelectedListView = this.Resources["IsSelectedCollectionView"] as CollectionViewSource;
if (isSelectedListView != null)
{
isSelectedListView .Source = App.ViewModel.Items;
}
}
}
private void CollectionViewSource_SelectedListFilter(object sender, System.Windows.Data.FilterEventArgs e)
{
e.Accepted = ((ItemViewModel)e.Item).IsSelected;
}
private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
ItemViewModel item = App.ViewModel.Items[App.ViewModel.Items.Count - 1];
item.IsSelected = !item.IsSelected;
}
}
यह भी ध्यान दें कि लोडिन के तुरंत बाद डेटा को जी, मैं CollectionViewSource
प्राप्त करता हूं और ObservableCollection<T>
सूची के रूप में अपना डेटा स्रोत सेट करता हूं, ताकि फ़िल्टरिंग हो सकने वाला मूल डेटा हो।
आवेदन भार, डेटा की उम्मीद के रूप में प्रदर्शित किया जाता है ObservableCollection<T>
जो IsSelected
सच है, दूसरी धुरी में प्रदर्शित किया जा रहा है में उन वस्तुओं के साथ,:
आपको लगता है कि मैं ध्यान देंगे क्लिक किए जाने पर ObservableCollection<T>
में अंतिम आइटम की IsSelected
संपत्ति को क्लिक करते समय एप्लिकेशन बार आइकन को अनमंत्रित किया गया है (MainPage.xaml.cs में अंतिम फ़ंक्शन देखें)।
यहाँ है मेरे सवाल की जड़ - जब मैं लागू बार आइकन पर क्लिक करें, मैं देख सकता जब सूची का अंतिम आइटम अपने IsSelected
संपत्ति सही पर सेट किया, howoever दूसरी धुरी इस बदली हुई आइटम प्रदर्शित नहीं करता है । मैं देख सकता हूं कि NotifyPropertyChanged()
हैंडलर को आइटम पर निकाल दिया जा रहा है, हालांकि संग्रह इस तथ्य को नहीं उठा रहा है, और इसलिए पिवोट 2 में सूची बॉक्स इस तथ्य को प्रतिबिंबित करने के लिए नहीं बदलता है कि संग्रह में एक नया आइटम जोड़ा जाना चाहिए ।
मुझे यकीन है कि मुझे कुछ मौलिक/बुनियादी कुछ याद आ रहा है, लेकिन असफल रहा है, क्या किसी को संग्रह प्राप्त करने का सबसे अच्छा तरीका पता है और यह खुशी से खेलने के लिए अंतर्निहित वस्तुओं को जानता है?
मुझे लगता है कि यह समस्या सॉर्टिंग के साथ-साथ फ़िल्टरिंग पर भी लागू होती है ((इस अर्थ में कि अगर CollectionViewSource
सॉर्टिंग पर आधारित है, तो जब किसी आइटम की एक प्रकार की प्रॉपर्टी का उपयोग किया जाता है, तो सॉर्ट ऑर्डर संग्रह को भी इस पर प्रतिबिंबित करना चाहिए))
मुझे एक ही समस्या है।हम उम्मीद करते हैं कि अंतर्निहित संग्रह में परिवर्तनों के आधार पर दृश्य गतिशील रूप से अपडेट हो जाए लेकिन यह नहीं है। तो यह वास्तव में सॉफ्टवेयर की एक समस्या है जो हम स्वाभाविक रूप से अपेक्षा करते हैं और/या एमएसडीएन दस्तावेज पूरा नहीं कर रहे हैं। – JustinM