none
Aus DataView Daten filtern und an weitere Verarbeitung geben mit rückwirkenden Änderungen RRS feed

  • Allgemeine Diskussion

  • Hallo, ich schildere mal mein Problem. Ich fahre aus drei Tabellen (SQL) eine gemeinsame Tabelle zusammen (LinQ).

    Ich generiere aus der Tabelle sofort eine DataView, die ich an diverse DataGrids verteile (zzur Visualisierung der Daten). Dann muss ich aus einem der DataGrids, das nur einen Teil der Datensätze anzeigt weitere Datensätze suchen, die in der gemeinsamen Tabelle enthalten sind,aber halt in diesem einen Grid nicht dargestellt wegen der Filtereinstellung. Das Problem das ich habe: Ich will diese Untersuchung in der ich weitere Datensätze bekomme an ein weiteres DataGrid übergeben und dort diverse Änderungen in die Datensätze eingeben lassen (per Code, automatisiert). Dann müssen die Daten ja auch in allen anderen DataGrids oder Anzeigeelementen aktualisiert werden, da diese an der DataView hängen.

    Mein Problem ist eben, das ich diese Datensätze, die ich untersuche, aus der gemeinsamen Tabelle hole und diese in eine separate Tabelle schreibe und eben "diese" an das DataGrid weitergebe. Somit haben aber meine Daten keinen Bezug zu der DataView, wodurch sich die Daten überall aktualisieren würden. Wie kann ich das am einfachsten machen, ohne alle Änderungen abzufangen und die Änderungen in sie Datensätze aintragen zu lassen?


    oema von MSDN

    Donnerstag, 3. Januar 2013 16:34

Alle Antworten

  • Hi,
    die Lösung ist ganz einfach:
     
    - es gibt nur einen Datenpuffer, z.B. eine DataTable oder ein LinQ-Ergebnis.ToList
     
    - für jede gefilterte Sicht gibt es eine CollectioViewSource, die als Source den gleichen Datenpuffer nutzen
    - jeder Oberflächenbereich mit eigener Filterung (z.B. jedes DataGrid) ist an eine eigene Eigenschaft gebunden
    - jede dieser ReadOnly-Eigenschaften vom Typ ICollectionView liefert von der zugehörigen CollectionViewSource die View-Eigenschaft
    - für jede dieser View-Eigenschaften sind die Filter und Sortkriterien festzulegen.
     
    --
    Peter Fleischer
    Freitag, 4. Januar 2013 12:16
  • Hallo Peter, inzwischen habe ich das so gemacht, das ich die Datensätze die ich benötige aus der Geneinschafttabelle hole und die benötigte in ein List<DataRow> fahre. Die Liste konnte ich dann in eine DataTable kopieren .CopyToDataTable().  Hat mir aber noch nichts gebracht. Jetzt muss ich daraus eine ListCollectionView bilden und diese dann dem DataGrid zuweisen, damit dann diese Daten wenn sie geändert werden auch an die anderen DataGrids zurückgegeben werden? Wennja, wie bilde ich daraus sie View für das DataGrid?

    So bekomme ich einen Fehler:

    CollectionViewSource collectionViewSource = (CollectionViewSource) CollectionViewSource.GetDefaultView(listCollectionView);


    oema von MSDN

    Sonntag, 6. Januar 2013 21:58
  • Hi,
    nachfolgend eine Demo als Anregung:
    <Window x:Class="WpfApplicationCS1.Window2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window2" Height="500" Width="600"
            xmlns:local="clr-namespace:WpfApplicationCS1">
      <Window.Resources>
        <local:ViewModel2 x:Key="vm"/>
      </Window.Resources>
      <StackPanel DataContext="{Binding Source={StaticResource vm}}" Orientation="Horizontal">
        <DataGrid Width="170" ItemsSource="{Binding View1}" Margin="10" />
        <DataGrid Width="170" ItemsSource="{Binding View2}" Margin="10" />
        <DataGrid Width="170" ItemsSource="{Binding View3}" Margin="10" />
      </StackPanel>
    </Window>
    

    Dazu der ViewModel:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Data;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApplicationCS1
    {
    
      public class ViewModel2
      {
    
        public ViewModel2()
        {
          liste = GetData();
        }
    
        private ObservableCollection<C1> liste = new ObservableCollection<C1>();
    
        public ICollectionView View1
        {
          get
          {
            CollectionViewSource cvs = new CollectionViewSource();
            cvs.Source = liste;
            return cvs.View;
          }
        }
    
        public ICollectionView View2
        {
          get
          {
            CollectionViewSource cvs = new CollectionViewSource();
            cvs.Source = liste;
            cvs.View.Filter = new Predicate<object>((c) => { return ((C1)c).kz1; }); 
            return cvs.View;
          }
        }
    
        public ICollectionView View3
        {
          get
          {
            CollectionViewSource cvs = new CollectionViewSource();
            cvs.Source = liste;
            cvs.View.Filter = new Predicate<object>((c) => { return ((C1)c).kz2; });
            return cvs.View;
          }
        }
    
        public ObservableCollection<C1> GetData()
        {
          DataTable dt = new DataTable("Tab1");
          dt.Columns.Add("ID", typeof(int));
          dt.Columns[0].AutoIncrement = true;
          dt.Columns[0].AutoIncrementSeed = -1;
          dt.Columns[0].AutoIncrementStep = -1;
          dt.Columns.Add("col1", typeof(string));
          dt.Columns.Add("kz1", typeof(bool));
          dt.Columns.Add("kz2", typeof(bool));
          Random rnd = new Random();
          for (int i = 0; i < 100; i++)
          {
            DataRow r = dt.NewRow();
            r[1] = "Zeile " + i.ToString();
            r[2] = rnd.NextDouble() < ..5;
            r[3] = rnd.NextDouble() < ..5;
            dt.Rows.Add(r);
          }
          return new ObservableCollection<C1>(from row in dt.AsEnumerable()
                                              select new C1()
                                              {
                                                ID = (int)row[0],
                                                col1 = (string)row[1],
                                                kz1 = (bool)row[2],
                                                kz2 = (bool)row[3]
                                              });
        }
    
        public class C1
        {
          public int ID { get; set; }
          public string col1 { get; set; }
          public bool kz1 { get; set; }
          public bool kz2 { get; set; }
        }
    
      }
    
    }
    
    

    --
    Viele Gruesse
    Peter

    Donnerstag, 10. Januar 2013 14:43
  • Hallo Peter, habe das gerade erst gesehen. Sieht mir so aus, als ob man so auch verschiedene Tabellen miteinander kombinieren kann. Das würde dann ja auch einen enormen Geschwindigkeitsvorteil bringen, oder? Wenn das so sein sollte, muss ich mir das mal genauer ansehen, denn im Moment schaufle ich zwei Tabellen von server1 und eine View von  server2 über Linq mit Join zusammen.

    Kann man eigentlich auch Daten von verschiedenen SQL-Servern in C# direkt abrufen und verjoinen?


    oema von MSDN

    Donnerstag, 24. Januar 2013 23:05
  • Hi,
    eine verknüpfte Abfrage über 2 Verbindungen ist mir nicht bekannt. Das unterstützte früher mal die Jet. Da konnte man mit OleDb 2 Access Dateien abfragen. Zum Verknüpfen sehe ich LinQ to Objects als optimalen Weg.
     
    --
    Peter Fleischer
    Freitag, 25. Januar 2013 05:56