none
CollectionViewSource an Datatable binden RRS feed

  • Frage

  • Hallo

    Ich habe 2 Datagrids die jeweils einen Teil einer Tabelle anzeigen sollen. Sie zeigen aber beide das Gleiche an. Die Datagrids sind über

    DataContext="{StaticResource sportlerTeam1ViewSource}

    bzw.

    DataContext="{StaticResource sportlerTeam2ViewSource}

    an eine ViewSource gebunden

    <local:ImasDataSet x:Key="imasDataSet"/>
    <CollectionViewSource x:Key="sportlerTeam1ViewSource" Source="{Binding Sportler, Source={StaticResource imasDataSet}}"/>
    <CollectionViewSource x:Key="sportlerTeam2ViewSource" Source="{Binding Sportler, Source={StaticResource imasDataSet}}"/>

    und mit folgendem Code fülle ich die Datatables dazu

    imasDataSetSportlerTeam1TableAdapter.FillByTeam1(imasDataSet.Sportler);
    sportlerTeam1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("sportlerTeam1ViewSource")));
    sportlerTeam1ViewSource.View.MoveCurrentToFirst();
      
    imasDataSetSportlerTeam2TableAdapter.FillByTeam2(imasDataSet.Sportler);
    sportlerTeam2ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("sportlerTeam2ViewSource")));
    sportlerTeam3ViewSource.View.MoveCurrentToFirst();

    Problem ist jetzt das Die Datagrids(Viewsources) mit dem DataSet und nicht mit dem richtigen Tbleadapter verbunden sind. Also zeigen sie immer das gleiche an. In diesem Fall zeigen sie an was zulöetzt geladen wurde. Alsonur alle Sportler von Team 2

    imasDataSetSportlerTeam2TableAdapter.FillByTeam2(imasDataSet.Sportler);

    Wie kann ich jetzt sagen das die Collectionviewsource nicht auf mein Dataset sondern auf eine der beiden Tables zugreift?

    Danke schonmal




    Freitag, 23. Mai 2014 12:04

Antworten

  • Hi,
    nachfolgend mal eine Demo:

    XAML:

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="600" Width="525"
            xmlns:local="clr-namespace:WpfApplication3">
      <Window.Resources>
        <local:ViewModel x:Key="vm"/>
      </Window.Resources>
      <StackPanel DataContext="{Binding Source={StaticResource vm}}">
        <DataGrid ItemsSource="{Binding View1}" />
        <DataGrid ItemsSource="{Binding View2}" />
      </StackPanel>
    </Window>
    

    Dazu der ViewModel:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Data;
    using System.Windows.Data;
    
    namespace WpfApplication3
    {
      class ViewModel
      {
    
        ObservableCollection<DS1.SportlerRow> liste;
        CollectionViewSource cvs1;
        CollectionViewSource cvs2;
    
        public ViewModel()
        {
          SporterLaden();
        }
    
        private void SporterLaden()
        {
          DS1 imasDataSet = new DS1();
          DataTable dt = imasDataSet.Sportler;
          for (int i = 1; i <= 20; i++)
          {
            DS1.SportlerRow r = dt.NewRow() as DS1.SportlerRow;
            r.ID = i;
            dt.Rows.Add(r);
          }
          liste = new ObservableCollection<DS1.SportlerRow>( imasDataSet.Sportler.AsEnumerable());
        }
    
        public ICollectionView View1
        {
          get
          {
            if (cvs1 == null)
            {
              cvs1 = new CollectionViewSource();
              cvs1.Source = liste;
              cvs1.View.Filter = delegate(object obj)
              {
                return ((DS1.SportlerRow)obj).ID <= 10;
              };
            }
            return cvs1.View;
          }
        }
        public ICollectionView View2
        {
          get
          {
            if (cvs2 == null)
            {
              cvs2 = new CollectionViewSource();
              cvs2.Source = liste; 
              cvs2.View.Filter = delegate(object obj)
              {
                return ((DS1.SportlerRow)obj).ID > 10;
              };
            }
            return cvs2.View;
          }
        }
      }
    
    }

    --
    Peter

    Montag, 26. Mai 2014 18:58

Alle Antworten

  • Hi,
    wichtig ist zu unterscheiden, wo Daten gepuffert werden und wo Sichten auf die gepufferten Daten erstellt werden.

    Datenquelle für die Anzeige (=Datenpuffer) ist in Deinem Code imasDataSet. Der letzte Füllvorgang ist die Basis der angezeigten Daten.

    Die beiden Sichten sind zwar unterschiedliche Objekte, wenn sie aber als Datenquelle den gleichen Datenpuffer nutzen, stellen sie die gleichen Daten für die Anzeige bereit. Lediglich, wenn Sort- oder Filterkriterien in den Sichten gesetzt werden würden, könnten unterschiedliche Anzeigen möglich sein.

     Es gibt 2 Wege zur Lösung Deines Problems, entweder Du nutzt unterschiedliche Datenpuffer oder Du lädst alle Daten in einen Datenpuffer und nutzt Filter.

    --
    Peter

    Freitag, 23. Mai 2014 19:53
  • Hallo. Danke für die Antwort.

    Aber habe ich nicht eigentlich 2 Datenpuffer wenn ich jeweils eine eigene Datatable verwende?

    imasDataSetSportlerTeam1TableAdapter.FillByTeam1(imasDataSet.Sportler);

    imasDataSetSportlerTeam2TableAdapter.FillByTeam2(imasDataSet.Sportler);

    Wenn ich das einzeln verwende geht es auch. Nur wenn ich 2 DGs habe gehts nicht.Aber ich weiß nicht wie ich das mit dem sportlerTeam1ViewSource.Filter machen soll, da das eine DG die Sportlertabelle mit den IDs 1-10 und das 2. DG die IDs 11-20 anzeigen soll.

    Hat jemand eine Idee?

    Montag, 26. Mai 2014 06:09
  • Also ich habe jetzt alles auf dem selben Datset. und möchte die CollectionView filtern

    <CollectionViewSource x:Key="sportlerTeam1ViewSource" Filter="FilterTeam1" Source="{Binding Sportler, Source={StaticResource imasDataSet}}"/>
    und rufe diese Funktion auf. Aber was muss ich dann als Objekt übergeben?

    private void FilterTeam1(object sender, FilterEventArgs e)
    {
    
    }

    Montag, 26. Mai 2014 10:15
  • Hi,
    mit dem 2. Füllen überschreibst Du die im 1. Füllvorgang geladenen Daten, da Du nur einen (den gleichen) Datenpuffer (imasDataSet.Sportler) nutzt.

    --
    Peter

    Montag, 26. Mai 2014 11:09
  • Ja das ist mir jetzt klar. Aber ich bekomme einfach das Filtern nicht hin.

    Kannst du mir helfen?

    Montag, 26. Mai 2014 11:24
  • Hi,
    nachfolgend mal eine Demo:

    XAML:

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="600" Width="525"
            xmlns:local="clr-namespace:WpfApplication3">
      <Window.Resources>
        <local:ViewModel x:Key="vm"/>
      </Window.Resources>
      <StackPanel DataContext="{Binding Source={StaticResource vm}}">
        <DataGrid ItemsSource="{Binding View1}" />
        <DataGrid ItemsSource="{Binding View2}" />
      </StackPanel>
    </Window>
    

    Dazu der ViewModel:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Data;
    using System.Windows.Data;
    
    namespace WpfApplication3
    {
      class ViewModel
      {
    
        ObservableCollection<DS1.SportlerRow> liste;
        CollectionViewSource cvs1;
        CollectionViewSource cvs2;
    
        public ViewModel()
        {
          SporterLaden();
        }
    
        private void SporterLaden()
        {
          DS1 imasDataSet = new DS1();
          DataTable dt = imasDataSet.Sportler;
          for (int i = 1; i <= 20; i++)
          {
            DS1.SportlerRow r = dt.NewRow() as DS1.SportlerRow;
            r.ID = i;
            dt.Rows.Add(r);
          }
          liste = new ObservableCollection<DS1.SportlerRow>( imasDataSet.Sportler.AsEnumerable());
        }
    
        public ICollectionView View1
        {
          get
          {
            if (cvs1 == null)
            {
              cvs1 = new CollectionViewSource();
              cvs1.Source = liste;
              cvs1.View.Filter = delegate(object obj)
              {
                return ((DS1.SportlerRow)obj).ID <= 10;
              };
            }
            return cvs1.View;
          }
        }
        public ICollectionView View2
        {
          get
          {
            if (cvs2 == null)
            {
              cvs2 = new CollectionViewSource();
              cvs2.Source = liste; 
              cvs2.View.Filter = delegate(object obj)
              {
                return ((DS1.SportlerRow)obj).ID > 10;
              };
            }
            return cvs2.View;
          }
        }
      }
    
    }

    --
    Peter

    Montag, 26. Mai 2014 18:58
  • Vielen Dank
    Dienstag, 27. Mai 2014 04:47