2010-11-05 4 views
2

J'ai créé une application winforms. Ce qu'il fait, c'est interroge une base de données et affiche les données sur un graphique à l'écran.C# débutants frustration avec les classes questions

ma question est, est-il approprié d'utiliser des classes pour cela? Je sais que la réponse est probablement oui, mais je n'ai aucune idée de comment utiliser une classe pour cela.

Voici mon code. s'il vous plaît me donner quelques conseils sur la façon de transformer cela en une classe si vous pensez que est la bonne chose à faire:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Windows.Forms.DataVisualization.Charting; 
using System.Data.OleDb; 
using System.Data.SqlClient; 

namespace WindowsFormsApplication1 
{ 

    public partial class Form1 : Form 
    { 

     public Form1() 
     { 
      InitializeComponent(); 
     } 
     private DataTable qResults = new DataTable(); 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      string qcvalues_query = "SELECT DISTINCT name FROM qvalues ORDER by name"; 
      string analytes_query = "SELECT DISTINCT compound FROM qvalues ORDER by compound"; 
      string instruments_query = "SELECT DISTINCT instrument FROM batchinfo WHERE instrument <> '' AND instrument is not Null ORDER by instrument"; 

      dataGridView1.MultiSelect = false; 

      cbAnalytes.DisplayMember = "name"; 
      cbAnalytes.DataSource = ConnectandReadList(qcvalues_query); 

      cbQCValues.DisplayMember = "compound"; 
      cbQCValues.DataSource = ConnectandReadList(analytes_query); 

      cbInstruments.DisplayMember = "instrument"; 
      cbInstruments.DataSource = ConnectandReadList(instruments_query); 
     } 
     private DataSet GetSeriesValues() 
     { 

      Series ser = this.chart1.Series["Series1"]; 

      DataSet dataSet = new DataSet(); 
      DataTable seriesTable = new DataTable(ser.Name); 

      seriesTable.Columns.Add(new DataColumn("No", typeof(int))); 
      seriesTable.Columns.Add(new DataColumn("X", typeof(string))); 
      seriesTable.Columns.Add(new DataColumn("Y", typeof(double))); 

      for (int count = 0; count < ser.Points.Count; count++) 
      { 
       DataPoint p = ser.Points[count]; 
       seriesTable.Rows.Add(new object[] { count, p.XValue, p.YValues[0] }); 
      } 

      dataSet.Tables.Add(seriesTable); 
      return dataSet; 
     } 

     private void chart1_MouseMove(object sender, MouseEventArgs e) 
     { 
      // Call Hit Test Method 
      HitTestResult result = chart1.HitTest(e.X, e.Y); 

      // Reset Data Point Attributes 
      foreach (DataPoint point in chart1.Series[0].Points) 
      { 
       point.BackSecondaryColor = Color.Black; 
       point.BackHatchStyle = ChartHatchStyle.None; 
       point.BorderWidth = 1; 
      } 

      // If a Data Point or a Legend item is selected. 
      if 
      (result.ChartElementType == ChartElementType.DataPoint || 
       result.ChartElementType == ChartElementType.LegendItem) 

       { 
        try 
        { 
         // Set cursor type 
         this.Cursor = Cursors.Hand; 


         // Find selected data point 
         DataPoint point = chart1.Series[0].Points[result.PointIndex]; 

         // Set End Gradient Color to White 
         point.BackSecondaryColor = Color.White; 

         // Set selected hatch style 
         point.BackHatchStyle = ChartHatchStyle.Percent25; 

         // Increase border width 
         point.BorderWidth = 2; 
        } 
        catch { } 
       } 
      else 
      { 
       // Set default cursor 
       this.Cursor = Cursors.Default; 
      } 
     } 


     private void InitializeChart() 
     { 
      chart1.Series["Series1"].ChartType = SeriesChartType.Line; 
      chart1.Series["Series1"].MarkerStyle = MarkerStyle.Circle; 
      chart1.Series["Series1"].MarkerSize = 8; 

      // Set series members names for the X and Y values 
      chart1.Series["Series1"].XValueMember = "datapath"; 
      chart1.Series["Series1"].YValueMembers = "finalconc"; 



      chart1.DataBind(); 

      // Calculate Mean 
      double mean = chart1.DataManipulator.Statistics.Mean("Series1"); 

      // Calculate Median 
      double median = chart1.DataManipulator.Statistics.Median("Series1"); 

      // Calculate Standard Deviation from the Variance 
      double variance = chart1.DataManipulator.Statistics.Variance("Series1", true); 
      double standardDeviation = Math.Sqrt(variance); 

      // Set Strip line item 
      chart1.ChartAreas[0].AxisY.StripLines[0].IntervalOffset = mean - Math.Sqrt(variance); 
      chart1.ChartAreas[0].AxisY.StripLines[0].StripWidth = 2.0 * Math.Sqrt(variance); 

      // Set Strip line item 
      chart1.ChartAreas[0].AxisY.StripLines[1].IntervalOffset = mean; 

      // Set Strip line item 
      chart1.ChartAreas[0].AxisY.StripLines[2].IntervalOffset = median; 

      DataPoint maxValuePoint = chart1.Series["Series1"].Points.FindMaxByValue(); 
      DataPoint minValuePoint = chart1.Series["Series1"].Points.FindMinByValue(); 

      chart1.ChartAreas[0].AxisY.Maximum = maxValuePoint.YValues.Max(); 
      chart1.ChartAreas[0].AxisY.Minimum = minValuePoint.YValues.Min(); 

      // Refresh Chart 
      chart1.Invalidate(); 

     } 

     private DataTable ConnectandReadList(string query) 
     { 
      DataTable ds = new DataTable(); 
      string connection_string = "Data Source=hermes;database=qcvalues; Integrated Security=SSPI;"; 
      using (var myConnection = new SqlConnection(connection_string)) 
      { 
       myConnection.Open(); 
       var command = new SqlCommand(query, myConnection); 
       var adapter = new SqlDataAdapter(command); 
       adapter.Fill(ds); 
      } 
      return ds; 
     } 


     private void btnGenerateGraph_Click(object sender, EventArgs e) 
     { 
      string graph_query = @"SELECT top 1000 reporttime, 
        datapath, 
        finalconc, 
        instrument 
        FROM batchinfo 
        JOIN qvalues ON batchinfo.rowid = qvalues.rowid 
        WHERE compound = '" + cbQCValues.Text + "'" + 
        "AND name = '" + cbAnalytes.Text + "'" + 
        "AND batchinfo.instrument = '" + cbInstruments.Text + "'" + 
        "AND batchinfo.reporttime LIKE '10/%/2010%'"; 


      qResults = ConnectandReadList(graph_query); 
      if (qResults.Rows.Count == 0) 
      { 
       MessageBox.Show("Your query did not return any results!"); 
       return; 
      } 

      chart1.DataSource = qResults; 
      InitializeChart(); 


      dataGridView1.Columns.Clear(); 
      dataGridView1.DataBindings.Clear(); 
      dataGridView1.DataSource = qResults; 

     } 

     private void chart1_MouseDown(object sender, MouseEventArgs e) 
     { 
      // Call Hit Test Method 
      HitTestResult result = chart1.HitTest(e.X, e.Y); 

      if (result.ChartElementType == ChartElementType.DataPoint) 
      { 

       dataGridView1.Rows[result.PointIndex].Selected = true; 
       dataGridView1.FirstDisplayedScrollingRowIndex = result.PointIndex; 

      } 


     } 

     private void btnDelete_Click(object sender, EventArgs e) 
     { 
      Int32 selectedRowCount = 
     dataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected); 
      if (selectedRowCount == 1) 
      {         
       qResults.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index); 
       InitializeChart();       

      } 
     } 


    } 
} 
+5

'Form1' est une classe. – SLaks

+0

@slaks vous devriez vous préparer pour shabbas ne pas perdre de temps ici –

+0

Je vais laisser cela aux grands chiens pour répondre, mais la question la plus importante est ce qui arrivera à ce plus tard? Le but unique de ce programme est-il * d'afficher * l'information? Ensuite, vous n'avez probablement pas besoin de vous soucier de rendre cet objet plus orienté objet qu'il ne l'est déjà. Si cela peut être utilisé pour plus dans le futur, alors vous feriez bien d'envisager un peu plus d'orientation de l'objet dans vos données. – Crisfole

Répondre

1

Je suis avec des slaks à ce sujet. Form1 est une classe.

Le seul vrai changement que je suggérerais à ce stade serait de transformer cela en une commande composite. De cette façon, vous pourriez laisser tomber cette fonctionnalité sur différentes formes si nécessaire.

Consultez le MS walkthrough et un smaller article here.

Vous pourriez le faire pour aucune autre raison que d'apprendre quelque chose de nouveau.

2

Comment vous organisez votre code dépend de l'ampleur et de la complexité de votre application.

Si vous écrivez une application volumineuse, vous voudrez probablement utiliser différentes couches pour gérer la base de données, la logique métier et la présentation.

Pour une petite application comme la vôtre, il est probablement plus simple d'utiliser la liaison de données directement à une requête de base de données.

2

Vous utilisez déjà des classes, mais pas la manière la plus propre et la plus modulaire. Il est généralement considéré comme une mauvaise idée de combiner votre manipulation de données et votre logique métier dans une seule classe d'interface utilisateur. C'est pourquoi le MVC composite pattern a été inventé, pour séparer vos données, l'interface utilisateur et la logique biz dans des pièces plus modulaires.

Here's another article, spécifique au C# à regarder.

2

Je pense que c'est une question subjective ... Si cela fonctionne déjà, pourquoi le réparer? Mais d'un autre point de vue, si cela faisait partie d'un système plus important, je le diviserais non seulement en classes séparées, mais en assemblages et espaces de noms séparés.

Votre code est correct pour la tâche en cours. Je ne m'inquiéterais pas pour le moment, sauf si vous êtes déjà un programmeur compétent (connaissez la syntaxe) et que l'objectif est de mettre en œuvre une bonne conception de système modulaire pour un système à plus grande échelle.

+1

Je veux m'entraîner à faire les choses correctement –

+1

@iamagirl: Alors Quelle est la taille du projet? Vous pourriez vouloir le diviser en assemblages séparés pour le code d'accès aux données et pour la logique de l'interface utilisateur. Peut-être même à travers un niveau de logique métier/couche dans le mélange. la conception du système est également à propos de plus que de simplement diviser des choses en classes. Les classes doivent être bien conçues pour leur tâche. Ce que je dis, c'est qu'une réponse SO ne peut pas couvrir tout le terrain qu'une réponse correcte nécessite, c'est plus de choses que des livres sur l'adresse du sujet ... –