Springen naar inhoud


Tutorial info

  • Toegevoegd op: 14 jul 2012 14:23
  • Datum bijgewerkt: 14 jul 2012 15:16
  • Bekeken: 2375
 


* * * * *
1 Beoordeling

Werken met CollectionView in WPF (filteren, sorteren, Groep, navigeren)

Hoe te werken met het CollectionView.

Geplaatst door pascalbianca op14 jul 2012 14:23
Wat is een CollectionView?

Het is een laag die loopt over de Data Objects waarmee u regels kunt definiëren voor het sorteren, filteren, groeperen etc en manipuleren van de weergave van gegevens in plaats van het wijzigen van de feitelijke gegevens objecten. In andere woorden, een CollectionView is een klasse die zorg draagt ​​voor de totale overzicht en geeft ons de mogelijkheid om bepaalde functies op te nemen om te gebruiken.

Hoe maak je een CollectionView krijgen?

Je hoeft alleen de opsomming door te geven aan de CollectionViewSource.GetDefaultView dan ze te definieren.


C Code:
this.ListboxControl.ItemsSource = this.Source;

Je moet dus het volgende schrijven.:

C Code:
this.ListboxControl.ItemsSource = CollectionViewSource.GetDefaultView(this.Source);

De lijst krijgt de CollectionView die het nodig heeft.

collection1.jpg

Dus de CollectionView scheidt eigenlijk de View object Lijst Control met de werkelijke DataSource en geeft daarmee een interface om de gegevens te manipuleren als gevolg van de View objecten. Laten we nu eens kijken hoe je de basisfuncties voor de ICollectionView moet implementeren.

Sorteren

Sorteren kan worden toegepast op de CollectionView op een eenvoudige wijze. Je moet een SortDescription toevoegen aan de CollectionView. De CollectionView houdt in feite een stapel SortDescription objecten in, elk van hen, is een structuur en kan informatie van een kolom en de richting van sorteren inhouden. U kunt ze in de collectionView met de gewenste uitvoer krijgen.

Stel

dat ik de CollectionView opsla als een eigenschap:
C Code:
ICollectionView Source { get; set; }

Nu als je de bestaande collectie wilt sorteren:
C Code:
this.Source.SortDescriptions.Add(new SortDescription("Naam", ListSortDirection.Descending));

Vandaar dat de CollectionView zal worden gesorteerd op basis van Naam en in aflopende volgorde.

Opmerking: Het standaard gedrag van CollectionView is automatisch vernieuwen wanneer er een nieuwe SortDescription wordt toegevoegd. Voor de prestaties probleem, kunt u gebruik maken van DeferRefresh().

Groepering

U kunt aangepaste groep voor ICollectionView op dezelfde manier als jij voor het sorteren. Om Groep van elementen te creëren moet je GroupStyle gebruiken om de sjabloon te definiëren voor de Groep en de naam van de Groep in groepskoptekst te laten zien.

XAML Code:
<ListView.GroupStyle>
	<GroupStyle>
		<GroupStyle.HeaderTemplate>
			<DataTemplate>
				<TextBlock Text="{Binding Name}" />
			</DataTemplate>
		</GroupStyle.HeaderTemplate>
	</GroupStyle>
</ListView.GroupStyle>

Hier is de groep HeaderTemplate zo te bepalen elke groep de TextBlock de naam van de groep voorwerp waarmee de groep is weergegeven. U kunt meer dan een samenwerkingsverband voor een enkele collectie maken. Om een ​​collectie die u moet gebruiken te groeperen:

C Code:
this.Source.GroupDescriptions.Add(new PropertyGroupDescription("Afdeling"));

Let op: Groepering gaat uit van virtualisatie. Dus als u te maken hebt met grote hoeveelheid gegevens, kunnen grote groepen leiden tot prestatie-problemen.

Filteren

Filteren is een delicate kwestie.
C Code:
this.Source.Filter = item =>
{
	ViewItem vitem = item as ViewItem;
	if (vitem == null) return false;

	return  vitem.Name.Contains("A");

};

Hierboven worden slechts die onderdelen gesorteerd die een A in hun naam hebben.


Huidige record Manipulatie

ICollectionView maakt het ook mogelijk om items te synchroniseren met de huidige positie van het element in de CollectionView. Elke ItemsControl in de basis klasse van een ListControl in WPF onthult een eigenschap genaamd IsSynchronizedWithCurrentItem (wanneer is ingesteld op true) wordt automatisch de huidige positie van de CollectionView synchroon houdt.

Er zijn methoden zoals:
C Code:
this.Source.MoveCurrentToFirst();
this.Source.MoveCurrentToPrevious();
this.Source.MoveCurrentToNext();
this.Source.MoveCurrentToLast();

Deze stelt u in staat om te navigeren op de CurrentItem van de CollectionView.

Voorbeeld Programma

Om alle functies te tonen, heb ik Voorbeeld programma erbij gedaan waarmee je kunt sorteren, filteren, Groep en tussen de data-objecten navigeren. We gaan eens kijken hoe het werkt.:

f1.png

De applicatie bevat een ListView die weinig gegevens bevat. De kop is gemaakt met behulp van GridView die kan worden geklikt en op basis waarvan de items zijn gesorteerd.

XAML Code:
<ListView.View>
				<GridView AllowsColumnReorder="True">
					<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" />
					<GridViewColumn Header="Naam">
						<GridViewColumn.CellTemplate>
							<DataTemplate>
								<Grid>
									<TextBlock Text="{Binding Path=Naam}" Style="{StaticResource ListViewUnSelected}"/>
									<TextBox Text="{Binding Path=Naam}" Style="{StaticResource ListViewSelected}" />
								</Grid>
							</DataTemplate>
						</GridViewColumn.CellTemplate>
					</GridViewColumn>
					<GridViewColumn Header="Ontwikkelaar">
						<GridViewColumn.CellTemplate>
							<DataTemplate>
								<Grid>
									<TextBlock Text="{Binding Path=Ontwikkelaar}" Style="{StaticResource ListViewUnSelected}" />
									<ComboBox SelectedItem="{Binding Path=Ontwikkelaar}" ItemsSource="{Binding ElementName=mainWin, Path=DeveloperList}" Style="{StaticResource ListViewSelected}" />
								</Grid>
							</DataTemplate>
						</GridViewColumn.CellTemplate>
					</GridViewColumn>
					<GridViewColumn Header="Salaris">
						<GridViewColumn.CellTemplate>
							<DataTemplate>
								<Grid>
									<TextBlock Text="{Binding Path=Salaris}" Style="{StaticResource ListViewUnSelected}" />
									<TextBox Text="{Binding Path=Salaris}" Style="{StaticResource ListViewSelected}" />
								</Grid>
							</DataTemplate>
						</GridViewColumn.CellTemplate>
					</GridViewColumn>
				</GridView>
			</ListView.View>
		</ListView>

f2.png

In de bovenstaande afbeelding is te zien hoe de items automatisch wordt gesorteerd als de header wordt geklikt. Om dit te verwerken heb ik GridViewColumnHeader.Click waarmee je je controle over de kolom waarin erop wordt geklikt.

f2.png

C Code:
private void ListView_Click(object sender, RoutedEventArgs e)
		{
			GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
			if(currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
			{
				using (this.Source.DeferRefresh())
				{
					Func<SortDescription, bool> lamda = item => item.PropertyName.Equals(currentHeader.Column.Header.ToString());
					if (this.Source.SortDescriptions.Count(lamda) > 0)
					{
						SortDescription currentSortDescription = this.Source.SortDescriptions.First(lamda);
						ListSortDirection sortDescription = currentSortDescription.Direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending;


						currentHeader.Column.HeaderTemplate = currentSortDescription.Direction == ListSortDirection.Ascending ?
							this.Resources["HeaderTemplateArrowDown"] as DataTemplate : this.Resources["HeaderTemplateArrowUp"] as DataTemplate;

						this.Source.SortDescriptions.Remove(currentSortDescription);
						this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), sortDescription));
					}
					else
						this.Source.SortDescriptions.Add(new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
				}				 


			}


		}


Als je dan met bovenstaande code bv. gaat sorteren krijgt men bv. dit.:

f3.png

De FilterBy sectie stelt u in staat om te werken met de omgang van de filterse. U kunt de kolomnaam uit de ComboBox selecteren en toepassen van de selectiecriteria voor de kolom. Om dit te doen hebben we FilterButton Klik commando.
C Code:
this.Source.Filter = item =>
			{
				ViewItem vitem = item as ViewItem;
				if (vitem == null) return false;

				PropertyInfo info = item.GetType().GetProperty(cmbProperty.Text);
				if (info == null) return false;

				return  info.GetValue(vitem,null).ToString().Contains(txtFilter.Text);

			};

U kunt groep secties groeperen op basis van kolom Naam. Hier kunt u zien dat de items op Ontwikkelaars namen zijn gegroepeerd. De toegepaste groepskoptekst zal getoond worden in de groep Koptekst sectie.  

C Code:
this.Source.GroupDescriptions.Clear();

			PropertyInfo pinfo = typeof(ViewItem).GetProperty(cmbGroups.Text);
			if (pinfo != null)
				this.Source.GroupDescriptions.Add(new PropertyGroupDescription(pinfo.Name));

f4.png

Om te laten zien dat in-place editing ook kan, heb ik een aparte controle geplaatst voor het bewerken van elk geselecteerde rij. Het geselecteerde item wordt automatisch gedetecteerd met behulp van RelativeSource in de ListView DataColumn selector.

Bijvoorbeeld:

XAML Code:
 <GridViewColumn Header="Naam">
						<GridViewColumn.CellTemplate>
							<DataTemplate>
								<Grid>
									<TextBlock Text="{Binding Path=Naam}" Style="{StaticResource ListViewUnSelected}"/>
									<TextBox Text="{Binding Path=Naam}" Style="{StaticResource ListViewSelected}" />
								</Grid>
							</DataTemplate>
						</GridViewColumn.CellTemplate>
					</GridViewColumn>

Hier de vListViewSelected die de Style geeft van de TextBox, terwijl de ListViewUnselected de TextBlock zal laten zien. Als je kijkt naar de stijl hoe het eruit zal zien:

XAML Code:
<Style x:Key="ListViewUnSelected" TargetType="{x:Type TextBlock}">
   <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource convVis}, ConverterParameter=False}" />
</Style>
<Style x:Key="ListViewSelected" TargetType="{x:Type FrameworkElement}">
	<Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource convVis}, ConverterParameter=True}" />
</Style>


De RelativeSource FindAncestor zoekt de overeenkomstige ListViewItem iedere keer en bindt het met de IsSelected eigendom van het. Vandaar dat wanneer het item wordt geselecteerd, zal de CellTemplate automatisch wordt bijgewerkt met de Editor controles.

Het geselecteerd object knop toont eigenlijk een kort bericht op basis van de informatie in de huidige selectie.

C Code:
 private void btnEvaluate_Click(object sender, RoutedEventArgs e)
		{
			ViewItem item = this.lvItems.SelectedItem as ViewItem;

			string msg = string.Format("Hallo {0}, Ontwikkelaar in {1} met Salaris {2}", item.Naam, item.Ontwikkelaar, item.Salaris);
			MessageBox.Show(msg);
		}

Dus uit het plaatje hieronder zie je dat John een ontwikkelaar is in WPF.

f5.png

Hieronder heb ik ook het voorbeeld project erbij gedaan zodat jullie ook kunnen testen ;)

Bijlage  CollectionviewSourceSample.rar   94,68K   269 downloads

Inloggen


Untitled 1

Met dank aan Jürgen voor de jarenlange inzet van visualbasic.be (anno dec 2000)
Met dank aan Mike en Ronneke voor de jarenlange inzet van vbib.be (anno dec 2010)
Met dank aan PascalBianca voor de jarenlange inzet van vbib.be (anno dec 2016)