2010-05-26 11 views
20

Ich möchte an die Anzahl/Menge der Elemente in meinem DataContext binden.Bindung an Anzahl der Elemente im DataContext

Ich habe ein Objekt, sagen wir Person, die eine List<address> als eine Eigenschaft hat. Ich möchte die Anzahl der Adressen für diese Person anzeigen, dh: 5 oder 6 oder was auch immer der Fall sein mag.

Ich habe versucht {Binding Path=address#.Count} und ein paar andere, aber das scheint nicht zu funktionieren.

Jede Hilfe wäre dankbar, danke.

Antwort

24

Sie müssen den Namen der Eigenschaft binden, nicht ihren Typ.

C#:

public class Person 
{ 
    ... 
    public List<address> Addresses { get; set; } 
    ... 
} 

XAML:

{Binding Addresses.Count} 

Angenommen, Ihre DataContext ist ein Objekt vom Typ Person.

+0

Ich dachte, dass die Bindung an Object.Value Speicherlecks in WPF verursacht? – tcables

3

XAML:

<Window x:Class="CountDemo.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="CountDemo" Height="300" Width="300"> 
    <StackPanel> 
     <TextBlock Text="{Binding Path=Addresses.Count}" /> 
    </StackPanel> 
</Window> 

-Code hinter:

using System.Collections.Generic; 
using System.Windows; 

namespace CountDemo 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      DataContext = new Person(); 
     } 
    } 

    public class Person 
    { 
     public List<Address> Addresses 
     { 
      get { return new List<Address>() {new Address(), new Address(), new Address()}; } 
     } 
    } 

    public class Address 
    { 
    } 
} 
1

Um mit funktionellem Beispielcode auf tehMick's Antwort zu erweitern:

XAML:

<Window x:Class="Sandbox.Wpf.PropertyCount.PropertyCount" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Property Count" Height="300" Width="300"> 
    <StackPanel> 
     <ListView ItemsSource="{Binding Path=People}"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Grid Margin="4"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="Auto" /> 
          <ColumnDefinition Width="*" /> 
         </Grid.ColumnDefinitions> 
         <TextBlock Text="{Binding Path=Name}" Margin="3" /> 
         <TextBlock Grid.Column="1" Margin="3"> 
          <TextBlock Text="{Binding Path=Addresses.Count}" /> <Run>addresses</Run> 
         </TextBlock> 
        </Grid> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </StackPanel> 
</Window> 
Hinter

Code:

namespace Sandbox.Wpf.PropertyCount 
{ 
    /// <summary> 
    /// Interaction logic for PropertyCount.xaml 
    /// </summary> 
    public partial class PropertyCount : Window 
    { 

     public PropertyCount() 
     { 
      InitializeComponent(); 
      this.DataContext = new Model(); 
     } 
    } 

    public class Model 
    { 
     public List<Person> People { get; private set; } 

     public Model() 
     { 

      People = new List<Person>{ 
       new Person ("joe", new List<object> { 1, 2, 3 }), 
       new Person ("bob", new List<object> { 1, 2 }), 
       new Person ("kay", new List<object> { 1, 2, 3, 4, 5 }), 
       new Person ("jill", new List<object> { 1, 2, 3, 4 }), 
      }; 
     } 
    } 

    public class Person 
    { 
     public string Name { get; set; } 
     public List<object> Addresses { get; set; } 

     public Person(string name, List<object> addresses) 
     { 
      Name = name; 
      Addresses = addresses; 
     } 
    } 

} 
13

Wie tehMick sagt, können Sie den Pfad Addresses.Count mit binden.

Beachten Sie jedoch, dass es sei denn, Addresses ist ein ObservableCollection<address>, oder eine andere Art, die INotifyCollectionChanged implementiert, das Hinzufügen und Entfernen von Adressen wird die Anzahl auswirken, die nach ihrer ersten Anzeige in der Benutzeroberfläche angezeigt wird. Wenn Sie das benötigen, müssen Sie entweder den Typ der Auflistung in Ihrem Ansichtsmodell ändern (das ist am einfachsten) oder eine Eigenschaft in Ihrem Ansichtsmodell implementieren, die die Anzahl aufdeckt, und das Ereignis PropertyChanged jedes Mal auslösen, wenn Sie ein hinzufügen oder entfernen Adresse.

bearbeiten

ich eine Antwort liebeablesen, denken: „Hey, das ist nicht richtig“, und dann zu realisieren ich es geschrieben habe.

Wenn Sie an ein Objekt binden, dass nur implementiert INotifyCollectionChanged, die Zählung in der Benutzeroberfläche wird sich nicht ändern, wenn Elemente hinzugefügt oder ot der Sammlung entfernt. Das Objekt auch muss INotifyPropertyChanged implementieren und PropertyChanged erhöhen, wenn sich die Count Eigenschaft ändert.

Welche, zum Glück, ObservableCollection<T> tut. Also meine Antwort ist nicht , dass falsch.

0

In meinem Fall kam Roberts Antwort mir sehr nahe, was ich suchte. Ich füge jedoch viele Elemente aus einem Serviceanruf zur Liste hinzu und wollte nicht, dass das Ereignis für jedes Element ausgelöst wird. Zu diesem Zweck nutzte ich Funktionalität bereits in BindingList gebaut:

public class BindingListNotifyCount<T> : BindingList<T>, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected override void OnListChanged(ListChangedEventArgs e) 
    { 
     base.OnListChanged(e); 
     RaisePropertyChanged("Count"); 
    } 

    protected void RaisePropertyChanged([CallerMemberName]string propertyName = "") => 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

Dann einfach benutze ich es als:

displayItems.RaiseListChangedEvents = false; 
serviceItems.ForEach(item => displayItems.Add(item)); 
displayItems.RaiseListChangedEvents = true; 
displayItems.ResetBindings(); 
Verwandte Themen