none
Binding mit StaticResource funktioniert nicht RRS feed

  • Frage

  • Ich habe im XAML folgendes geschrieben (Ausschnitt):

    ItemSource = "{Binding Source={StaticResource cvs}}"
     
    Die Resource wurde wie folgt definiert:
     
    <CollectionViewSource x:Key="cvs" Source="{Binding}" Filter="Auswahl"/>
     
    Leider erhalte ich keine Ausgabe im Grid. Es funktoniert jedoch, wenn ich "{Binding Source={StaticResource cvs}}" gegen {Binding} ersetze... aber leider dann ohne Filter. Daten kommen über DataContext.
    Ich habe im Eventhandler zum Filter einen Breakpoint gesetzt, der jedoch nie erreicht wird.
     
    Hat jemand eine Idee, was ich falsch mache?
    
     
    Freitag, 3. Februar 2012 00:29

Antworten

  • Hi,

    mit folgendem funktioniert es (im Beispiel wird eine ListBox verwendet; das sollte für das Prinzip reichen).

    XAML:

    <Window.Resources>
       <CollectionViewSource
          x:Key="CollectionViewSource"
          Source="{Binding Path=TheList}" Filter="CollectionViewSource_Filter">
       </CollectionViewSource>
    </Window.Resources>
    
    <Grid>
          <TextBox
             VerticalAlignment="Top"
             Text="{Binding TheText, UpdateSourceTrigger=PropertyChanged}" />
       <ListBox
          Margin="0,40,0,0"
          DataContext="{StaticResource ResourceKey=CollectionViewSource}"
          ItemsSource="{Binding}" />
    </Grid>

    C#:

    public MainWindow()
    {
       ViewModel vm = new ViewModel();
       vm.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(vm_PropertyChanged);
       this.DataContext = vm;
    
       InitializeComponent();
    }
    
    private void vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
       CollectionViewSource resourcesViewSource = this.Resources["CollectionViewSource"] as CollectionViewSource;
       resourcesViewSource.View.Refresh();
    }
    
    private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
    {
       ViewModel vm = this.DataContext as ViewModel;
       e.Accepted = string.IsNullOrEmpty(vm.TheText) || e.Item.ToString().Contains(vm.TheText);
    }
    
    Das ViewModel besteht dabei aus einer List<string> "TheList" und einem einzelnen string "TheText" (dem Filter) und ein bisschen Mimik für INotifyPropertyChanged. Anzumerken ist nur, dass das "Neufiltern" extra angestoßen werden muss.

    Gruß
    Jürgen

    Sonntag, 12. Februar 2012 17:14

Alle Antworten

  • Kannst du das Filter='Auswahl' genauer definieren? Ist 'Auswahl' im code behind ein Predicate delegate? Werden beim Debuggen im Output Fenster vom Visual Studio Binding Fehler angezeigt?
    Freitag, 3. Februar 2012 07:30
  • Die Sub im CodeBehind ist eher trivial:

    PrivateSubAuswahl(sender AsObject, e AsFilterEventArgs)
    	e.Accepted = True
    End Sub

    Sollte ja eigentlich ein EventHandler sein, oder? Es sollten alle Elemente angezeigt werden... ich bekomme jedoch kein Element zu sehen. :-(

    Binding Fehler gab es nicht. Bei "Accepted" habe ich einen Breakpoint gesetzt, der jedoch nie erreicht wird. Sieht so aus, dass die Sub gar nicht aufgerufen wird...

    Freitag, 3. Februar 2012 15:59
  • Bei statischen CollectionViewSource kenne ich folgendes Vorgehen:

    Das Control, welches über die Resource gefüllt werden soll, bekommt DataContext="{StaticResource cvs}" und ItemsSource="{Binding}".

    Im Code behind befindet sich irgendwo (z.B. im Konstruktor, OnLoaded(), oder eine Eigenschaft) ein Code-Schnipsel, der die Source der Resource setzt:

    var cvs = (CollectionViewSource)this.Resources["cvs"];
    cvs.Source = <xyz>

    Sollte so klappen. Läuft bei mir problemlos.

    Viele Grüße
    Christoph

    Freitag, 10. Februar 2012 09:42
  • Hi,

    Christoph hat recht, allerdings ist der Code-behind Teil nicht nötig.

    Gruß
    Jürgen

    Samstag, 11. Februar 2012 18:32
  • Hallo Christoph und Jürgen,

    danke für Eure Antwort.

    Das Databinding funktionierte auch bereits vorher... das Problem ist, dass ich keinen Filter via XAML hinbekomme. Ich wollte mit einem EventHandler im codebehind arbeiten.

    Die Daten sind via DataContext direkt am UserControl angebunden und wird dann vererbt. Nun möchte ich die Daten je nach Auswahl eines TabItems filtern und via DataGrid im TabItem ausgeben. Das funktioniert mit etwas mehr codebehind gut... aber erscheint mir wegen MVVM nicht sauber.

    Folgenden Code habe ich geschrieben:

    <UserControl.Resources>
            <CollectionViewSource x:Key="cvs" Filter="Auswahl" />
    </UserControl.Resources>

    und danach:

    <TabItem x:Name="tiAll" DataContext="{StaticResource cvs}">
                    <DataGrid x:Name="Datagrid_TabItem" ItemsSource="{Binding}" usw.
    

    Den EventHandler habe ich wie oben im codebehind... soll halt alle Elemente erstmal darstellen, damit sehe, ob der Filter überhaupt funktioniert.

    Ich bekomme jedoch gar keinen Datensatz angezeigt und der EventHandler wird nicht angesprungen.

    Vermutung ist... die StaticResource ist nicht korrekt definiert.

    Vielleicht habt Ihr eine Idee?

    Sonntag, 12. Februar 2012 13:40
  • Hi,

    mit folgendem funktioniert es (im Beispiel wird eine ListBox verwendet; das sollte für das Prinzip reichen).

    XAML:

    <Window.Resources>
       <CollectionViewSource
          x:Key="CollectionViewSource"
          Source="{Binding Path=TheList}" Filter="CollectionViewSource_Filter">
       </CollectionViewSource>
    </Window.Resources>
    
    <Grid>
          <TextBox
             VerticalAlignment="Top"
             Text="{Binding TheText, UpdateSourceTrigger=PropertyChanged}" />
       <ListBox
          Margin="0,40,0,0"
          DataContext="{StaticResource ResourceKey=CollectionViewSource}"
          ItemsSource="{Binding}" />
    </Grid>

    C#:

    public MainWindow()
    {
       ViewModel vm = new ViewModel();
       vm.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(vm_PropertyChanged);
       this.DataContext = vm;
    
       InitializeComponent();
    }
    
    private void vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
       CollectionViewSource resourcesViewSource = this.Resources["CollectionViewSource"] as CollectionViewSource;
       resourcesViewSource.View.Refresh();
    }
    
    private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
    {
       ViewModel vm = this.DataContext as ViewModel;
       e.Accepted = string.IsNullOrEmpty(vm.TheText) || e.Item.ToString().Contains(vm.TheText);
    }
    
    Das ViewModel besteht dabei aus einer List<string> "TheList" und einem einzelnen string "TheText" (dem Filter) und ein bisschen Mimik für INotifyPropertyChanged. Anzumerken ist nur, dass das "Neufiltern" extra angestoßen werden muss.

    Gruß
    Jürgen

    Sonntag, 12. Februar 2012 17:14
  • Danke Jürgen,

    leider habe ich Schwierigkeiten, Dein Beispiel auf meins zu portieren.

    Würde es Dir was ausmachen, wenn Du Dir meinen Code einmal ansiehst (s.o.). Wo ist da der Fehler? Wieso funktioniert die Resource nicht? BTW... ich habe das als UserControl.Resource definiert. Ist das korrekt?

    Samstag, 18. Februar 2012 18:14
  • Hi,

    wo Du die Ressource platzierst ist egal. Du musst mit "resourcesViewSource" in

    resourcesViewSource.View.Refresh();

    halt die richtige Ressource instanziiert haben.

    Welche Schwierigkeiten hast Du bzw. wie weit kommst Du mit der Portierung. Bis wohin funktioniert es? Ab wo dann nicht mehr? Ich gehe dabei davon aus, dass Du schrittweise vorgehst und nicht 2000 Dinge auf einmal umstellst, von denen dann mindestens eins nicht funktioniert hat.

    Um Deinen Code nachvollziehen zu können, wäre es hilfreich, wenn Du den fraglichen Code (XAML, Code-behind, ViewModel) etwas kompletter posten könntest (soweit wie möglich mit Standard-Controls, damit nicht ein komplettes Projekt hier stehen muss). Dann - und wenn erkennbar ist, was Du bereits versucht hast - würde es mir nichts ausmachen.

    Gruß
    Jürgen

    Sonntag, 19. Februar 2012 13:56
  • ****************************************************************************************************************
    Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
    Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
    ****************************************************************************************************************

    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Mittwoch, 22. Februar 2012 08:27
    Moderator
  • Leider komme ich manchmal nicht sofort dazu, die Lösung anzuwenden.

    Mein Binding funktioniert jedoch nun. :-)

    Danke an alle Beteiligten.

    Sonntag, 4. März 2012 16:01
  • Hallo JasonMagnat,

    Ich möchte Dich bitten folgendes lesen und die Beiträge die Dir geholfen haben zu bewerten.

    Vielen Dank.

    Nutzen Sie die Bewertungsfunktionen ("Antwort" und "Hilfreich") in den MSDN Foren! Unter anderem können andere später eine Lösung schneller finden. Es ist also wünschenswert, dass die fragenden (Benutzer) die Postings/Beiträge anderer Beantworter bewerten.
    Hier dazu die wichtigsten Anhaltspunkte aus den Forenregeln und FAQs.

    Lösungsbeiträge als „Die Antwort“ markieren
    Bitte markieren Sie den Beitrag, der zur Lösung geführt hat, als "Die Antwort". Durch Bewerten eines Beitrags als "Die Antwort" können andere Teilnehmer die Lösung schneller finden. Außerdem können Sie dem Benutzer, der die Antwort eingereicht hat, für seinen Beitrag danken und zur Steigerung der Antwortqualität in der Diskussionsgruppe beitragen.
    [Quelle: Forenregeln]

    Wie bewerte ich einen Beitrag?Um einen Beitrag als hilfreich zu bewerten, klicken Sie in einem beliebigen Beitrag auf Als hilfreich bewerten. Sie können Ihre Stimme nur einmal für einen Beitrag abgeben.
    [Quelle: Häufig gestellte Fragen]

    Grüße,

    Robert



    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Montag, 5. März 2012 08:29
    Moderator