2016-12-12 4 views
0

私はCSVファイルを読み込んで、それをDateTableに変換するいくつかのコードを書いています。次のステップでは、DataTableを読み込んで特定の値を取得します。これらの値はオブジェクトに保存され、このオブジェクトはObserableCollectionに追加されます。WPFアプリケーションの数値オブジェクトが増加するのはなぜですか?

XAML:

<ListView ItemsSource="{Binding ProdOrderView}" x:Name="listView" Margin="9,70,112,34" AlternationCount="2" FontSize="14"> 
      <ListView.ItemContainerStyle> 
       <Style TargetType="{x:Type ListViewItem}"> 
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
        <Style.Triggers> 
         <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
          <Setter Property="Background" Value="White" /> 
         </Trigger> 
         <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
          <Setter Property="Background" Value="LightGray" /> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </ListView.ItemContainerStyle> 
      <ListView.View > 
       <GridView > 
        <GridViewColumn Header="Fauf" Width="Auto"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding Fauf}" TextAlignment="Right" Name="fauf"/> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="Prod-Start" Width="Auto"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding Start}" TextAlignment="Center" Name="start"/> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="Rück- &#xa;stand" Width="Auto"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock x:Name="inRueck" Text="{Binding InRueck}" TextAlignment="Center" /> 
           <DataTemplate.Triggers> 
            <DataTrigger Binding="{Binding InRueck, Converter={StaticResource ColorConverterInRueck}}" Value="delay"> 
             <Setter TargetName="inRueck" Property="Background" Value="Red" /> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding InRueck, Converter={StaticResource ColorConverterInRueck}}" Value="inTime"> 
             <Setter TargetName="inRueck" Property="Background" Value="Green" /> 
            </DataTrigger> 
           </DataTemplate.Triggers> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="heute" Width="Auto" > 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock x:Name="Heute" Text="{Binding Heute}" TextAlignment="Center" /> 
           <DataTemplate.Triggers> 
            <DataTrigger Binding="{Binding Heute}" Value="X"> 
             <Setter TargetName="Heute" Property="Background" Value="CornflowerBlue" /> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding Heute}" Value="?"> 
             <Setter TargetName="Heute" Property="Foreground" Value="DarkViolet" /> 
            </DataTrigger> 
           </DataTemplate.Triggers> 
          </DataTemplate> 

         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="morgen" Width="Auto" > 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding Morgen}" TextAlignment="Center" Name="Morgen"/> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="+2" Width="Auto" > 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding Uebermorgen}" TextAlignment="Center" Name="Uebermorgen"/> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       ... 

       </GridView> 
      </ListView.View> 
     </ListView> 

コードビハインド:

public MainWindow() 
    { 
     InitializeComponent(); 
     MainViewModel mvm = new MainViewModel(filepath,pline); 
     listView.ItemSource = mvm.ProdOrderView; 
    } 

MainViewModel:

class MainViewModel 
{ 
    #region Private Felder 
    private ObservableCollection<ProductionOrder> _prodOrderList; 

    private ListCollectionView _prodOrderView; 
    #endregion 

    #region Konstruktor 
    public MainViewModel(string filepath, string pline) 
    { 
     // ProductionOrderliste initialisieren 
     _prodOrderList = new ObservableCollection<ProductionOrder>();   

     _prodOrderList.Clear(); 
     fillObject(filepath, pline, ref _prodOrderList); 

     // ListCollectionView initialisieren 
     _prodOrderView = new ListCollectionView(_prodOrderList); 

    } 

    #endregion 

    #region Öffentliche Eigenschaften 
    public ListCollectionView ProdOrderView 
    { 
     get { return _prodOrderView; } 
    } 


    #endregion 

    #region ConvertCSVtoDataTabble 
    public DataTable ConvertCSVtoDataTable(string filename) 
    { 
     //DataTable anlegen 
     DataTable dataTable = new DataTable(); 
     dataTable.Columns.Clear(); 
     dataTable.Rows.Clear(); 
     dataTable.Clear(); 

     try 
     { 
      //Filestream anlegen, dadurch kann Datei auch gelesen werden, wenn sie geöffnet ist 
      FileStream logFileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

      using (StreamReader streamReader = new StreamReader(logFileStream)) 
      { 
       //Array mit allen Überschriften 
       string[] headers = streamReader.ReadLine().Split(';'); 
       //Schleife durchläuft das Array headers 
       foreach (string header in headers) 
       { 
        //Der DataTable wird eine Spalte mit dem aktuellen header (Überschrift) hinzugefügt. 
        dataTable.Columns.Add(header); 
       } 
       //Schleife, die so lange gültig ist bis das Ende des Streams erreicht wurde 
       while (!streamReader.EndOfStream) 
       { 
        //Array mit allen Zeilen füllen 
        string[] rows = streamReader.ReadLine().Split(';'); 


        //Der DataTable wird die Zeile mit dem aktuellen Werten der Zeile hinzugefügt. 
        dataTable.Rows.Add(rows); 
       } 
       //StreamReader wird geschlossen 
       streamReader.Close(); 
       //Filestream wird geschlossen 
       logFileStream.Close(); 
      } 
     } 
     catch(IndexOutOfRangeException e) 
     { 
      Console.WriteLine("Fehlercode:" + e); 
      ConvertCSVtoDataTable(filename); 
     } 
      //gefüllte DataTable wird zurückgegeben 
      return dataTable; 

     } 

    #endregion 

    #region fillObbject 
    public void fillObject(string filepath, string plinie, ref ObservableCollection<ProductionOrder> liste) 
    { 
     //DataTable res = new DataTable(); 
     //res.Columns.Clear(); 
     //res.Rows.Clear(); 
     //res.Clear(); 


     string emptyField = "\" \""; 
     DataTable res = ConvertCSVtoDataTable(filepath); 
     try 
     { 
      foreach (DataRow row in res.Rows) // Loop over the rows. 
      { 


       if (row["AFKO_PLTXT"].ToString() == plinie) 
       { 

        ////Objekt anlegen 
        ProductionOrder order = new ProductionOrder(); 

        //#region Prüft ob Sammelhinweis vorhanden 
        string sammel = ""; 
        Queue<string> queue = new Queue<string>(); 

        if (res.Columns.Contains("ZZTAG_MO")) 
        { 
         //Montag 
         if (row["ZZTAG_MO"].ToString() == "X") 
         { 
          sammel = "MO"; 
          queue.Enqueue(sammel); 
         } 
         //Dienstag 
         if (row["ZZTAG_DI"].ToString() == "X") 
         { 
          sammel = "DI"; 
          queue.Enqueue(sammel); 
         } 
         //Mittwoch 
         if (row["ZZTAG_MI"].ToString() == "X") 
         { 
          sammel = "MI"; 
          queue.Enqueue(sammel); 
         } 
         //Donnerstag 
         if (row["ZZTAG_DO"].ToString() == "X") 
         { 
          sammel = "DO"; 
          queue.Enqueue(sammel); 
         } 
         //Freitag 
         if (row["ZZTAG_FR"].ToString() == "X") 
         { 
          sammel = "FR"; 
          queue.Enqueue(sammel); 
         } 
         //Samstag 
         if (row["ZZTAG_SA"].ToString() == "X") 
         { 
          sammel = "SA"; 
          queue.Enqueue(sammel); 
         } 
         //Sonntag 
         if (row["ZZTAG_SO"].ToString() == "X") 
         { 
          sammel = "SO"; 
          queue.Enqueue(sammel); 
         } 


        } 
        // string sammelList wird zusammengesetzt 
        string sammelList = ""; 
        if (queue.Count > 0) 
        { 
         sammelList = "/"; 
         while (queue.Count > 0) 
         { 
          if (queue.Count > 1) 
           sammelList += queue.Dequeue() + "+"; 
          else 
          { 
           sammelList += queue.Dequeue(); 
          } 
         } 
        } 
        #endregion 
        //das Objekt wird mit den entsprechenden Werten gefüllt 
        order.Fauf = row["EXTRA_APO"].ToString(); 
        order.Start = row["GSTRP_KO"].ToString(); 
        order.Vorgang = row["LTXA1_AFVC"].ToString(); 
        order.Kundenauftrag = row["KDAUF_FK"].ToString() + sammelList; 
        order.Material = row["MATNR_PO"].ToString(); 
        order.Materialbezeichnung = row["MAKTX_MAKT"].ToString(); 
        order.Menge = row["AFKO_GAMNG"].ToString(); 
        order.WE_Menge = row["WEMNG_PO"].ToString(); 
        order.Ende = row["GLTRP_KO"].ToString(); 
        order.Notiz = row["NOTIZ_TEXT"].ToString(); 
        order.Ladedatum = row["LDDAT_VBEP"].ToString(); 
        order.Dauer = row["FAUFDAUER_REST_KO"].ToString(); 

        //führende Nullen werden entfernt falls vorhanden 
        order.Kundenauftrag = order.Kundenauftrag.TrimStart('0'); 
        order.Material = order.Material.TrimStart('0'); 

        if (order.Menge.Contains(",")) 
        { 
         order.Menge = order.Menge.Remove(order.Menge.IndexOf(@",")); 
        } 
        if (order.WE_Menge.Contains(",")) 
        { 
         order.WE_Menge = order.WE_Menge.Remove(order.WE_Menge.IndexOf(@",")); 
        } 
        order.Heute = ""; 
        order.Morgen = ""; 
        order.Uebermorgen = ""; 
        order.Plus3 = ""; 
        order.Plus4 = ""; 
        order.Plus5 = ""; 

        string inKlaerung = ""; 

        //konvertiert String zu Datetime 
        DateTime newStartDate = convertDateTime(order.Start); 
        order.Start = newStartDate.ToString("dd.MM.yyyy"); 


        //Berechne Verzug in Tagen 
        int verzugTage = (DateTime.Today - newStartDate).Days; 
        order.InRueck = verzugTage.ToString(); 

        //konvertiert String zu Datetime 
        var newLadedatum = convertDateTime(order.Ladedatum); 
        order.Ladedatum = newLadedatum.ToString("dd.MM.yyyy"); 
        if (inKlaerung != emptyField) 
        { 
         //X in der Spalte setzen, an dem Tag wo es gefertigt wird 
         if (verzugTage >= 0) 
         { 
          order.Heute = "X"; 
         } 
         else 
         { 
          switch (verzugTage) 
          { 
           case -1: 
            order.Morgen = "X"; 
            break; 
           case -2: 
            order.Uebermorgen = "X"; 
            break; 
           case -3: 
            order.Plus3 = "X"; 
            break; 
           case -4: 
            order.Plus4 = "X"; 
            break; 
           case -5: 
            order.Plus5 = "X"; 
            break; 
           default: 
            break; 
          } 

         } 
        } 
        else 
        { 
         order.Heute = "?"; 
        } 
        try 
        { 
         //konvertiert String zu Datetime 
         var newEndDate = convertDateTime(order.Ende); 
         order.Ende = newEndDate.ToString("dd.MM.yyyy"); 
        } 
        catch (FormatException e) 
        { 
         Console.WriteLine("Fehlercode:" + e); 
         order.Ende = "Fehler"; 
        } 

        // Prüft ob Vorgang leer ist 
        if (order.Vorgang == emptyField) 
        { 
         order.Vorgang = ""; 
        } 

        //Prüft ob Notiz leer ist 
        if (order.Notiz == emptyField) 
        { 
         order.Notiz = ""; 
        } 

        //Prüft ob Dauer leer ist 
        if (order.Dauer == emptyField) 
        { 
         order.Dauer = ""; 
        } 


        liste.Add(order);            
       } 
      }    
     } 

     catch (ArgumentException e) 
     { 

      Console.WriteLine("Fehlercode:" + e); 
     } 

    } 
    // #endregion 

    #region convertDateTime 
    public DateTime convertDateTime(string date) 
    { 
     //konvertiert String zu Datetime 
     DateTime newDate = DateTime.ParseExact(date, 
        "yyyyMMdd", 
         System.Globalization.CultureInfo.InvariantCulture); 
     return newDate; 

    } 
    #endregion 
} 
} 

私はCSVはオブジェクトの量は、まさにこだわり増える分ごとにファイルをロードする場合。ガベージコレクタは古いオブジェクトをすべてクリアしません。誰も私がこの問題を見つけるのを助けることができますか?

+0

を使用し、それは常に同じファイルである場合でも、それはデータ – MikeT

+0

との関係で直線的な成長すべきですか? – Nesslae

+0

新しいデータをロードしている場合は、はい、ロードが完了した後、GCは使用されていないオブジェクトをクリーンアップします。可能であればwpfが怠惰なローディングを利用することを覚えておいてください。グリッドに5000個のアイテムをロードすると、スクリーン上に実際に表示されるものだけがロードされるので、リストを下に移動すると、新しいアイテムがロードされます非常に複雑なこれはそれを行うための最良の方法です – MikeT

答えて

0

私の推測では、あなたの問題は、あなたが必要としないデータテーブルを使用しているということでしょう。

dataTableは基本的にコードベースのデータベーステーブルである非常に複雑な項目です。このため、MarshalByValueComponentという使用があります。これは自動的にGC'edできないことを示しています。それを使用し終わった。 (Disposeを呼び出すと、アンマネージコードへのリンクがクリーンアップされ、ガベージコレクタが利用できるようになります)。

はあなたが

(&のFileStream StreamReaderを含む)、非管理されているすべてのクラスのためにこれを行うために必要な2つの廃棄機能に簡単なコールを処分をトリガするためのオプションや使用方法(){}文

を持っていますあなたはデータテーブル、ちょうどテーブルとしてデータテーブルを使用していない

のように私はそれを完全に削除することをお勧めしてだけではなく、あなたのテキストファイルを解析

編集:ここでは

MVVMファイルパーサーの間に合わせモデルS

XAML:背後

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <local:FileViewModel x:Name="vm" /> 
    </Window.DataContext> 

    <DockPanel > 
     <DockPanel DockPanel.Dock="Top"> 
      <Button DockPanel.Dock="Right" Click="Button_Click">Read</Button> 
      <TextBox Text="{Binding File}" /> 
     </DockPanel> 
     <ListView ItemsSource="{Binding ItemCollection}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn DisplayMemberBinding="{Binding field1}" Header="Feild1"/> 
        <GridViewColumn DisplayMemberBinding="{Binding field2}" Header="Field2"/> 
        <GridViewColumn DisplayMemberBinding="{Binding field3}" Header="Field3"/> 
        <GridViewColumn DisplayMemberBinding="{Binding field4}" Header="Field4"/> 
       </GridView> 
      </ListView.View> 

     </ListView> 
    </DockPanel> 
</Window> 

コード:

ファイルリーダー

public class FileViewModel : INotifyPropertyChanged 
{ 
    private string _File; 

    public string File 
    { 
     get { return _File; } 
     set 
     { 
      _File = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("File")); 
     } 
    } 

    public ObservableCollection<ItemModel> ItemCollection { get; } = new ObservableCollection<ItemModel>(); 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void ReadFile() 
    { 
     ItemCollection.Clear(); 

     using (StreamReader reader = new StreamReader(File)) 
     { 
      var header = reader.ReadLine(); 
      while(!reader.EndOfStream) 
      { 
       var data = reader.ReadLine(); 
       var item = ItemModel.Create(header, data, ','); 
       ItemCollection.Add(item); 
      } 
     } 
    } 
} 

項目パーサ

public class ItemModel 
{ 
    public static ItemModel Create(string colstr, string datastr, char delimiter) 
    { 
     var cols = colstr.Split(delimiter); 
     var data = datastr.Split(delimiter); 

     var item = new ItemModel(); 

     item.field1 = int.Parse(GetValue(cols, data, "field1")); 
     item.field2 = DateTime.Parse(GetValue(cols, data, "field2")); 
     item.field3 = GetValue(cols, data, "field3"); 
     item.field4 = double.Parse(GetValue(cols, data, "field4")); 
     return item; 
    } 
    public static string GetValue(string[] cols, string[] data, string colName) 
    { 
     var colid = Array.IndexOf(cols, colName); 
     if (colid == -1) 
      return null; 
     else 
      return data[colid]; 
    } 

    public int field1 { get; set; } 
    public DateTime field2 { get; set; } 
    public string field3 { get; set; } 
    public double field4 { get; set; } 

} 

デモファイルは常に、あなたがコードに多くのデータをロードしているとして、いくつかの増加があるだろう

field2,field1,field4,field3 
01-Jan-16,1,1.1,a 
02-Jan-16,2,2.2,b 
03-Jan-16,3,3.3,c 
04-Jan-16,4,4.4,d 
+0

あなたの答えをありがとう。しかし、私がDataTableを使用している理由は、CSVに850の列があることです。そして、私はちょうどcaが必要です。 20.他の利点は、カラム名を持つこれらのカラムから値を取得できるため、カラムの順序とは無関係です。 名前の列で値を読み取るにはどうすればよいですか? – Nesslae

+0

私が回答に追加した例を見てください – MikeT

関連する問題