2012-05-11 22 views
5

दिखाता है मेरे पास एक फॉर्म है जिसमें एक चित्र बॉक्स है। जब फॉर्म डिफ़ॉल्ट छवि लोड लोड करता है ठीक है। मैं तब छवि को अद्यतन करता हूं जब मेरे रूप में कुछ बदलता है जो छवि को प्रदर्शित करता है। इस छवि की पीढ़ी भी ठीक काम करती है, मैं डिस्क पर छवि देख सकता हूं और इसे पेंट के साथ खोल सकता हूं। सामान्य रूप से मैं जो करता हूं वह छवि स्थान पर एक फ़ाइल स्ट्रीम खोलता है और फिर छवि को इस स्थान पर सेट करता है।विनफॉर्म पिक्चरबॉक्स छवि खाली सी #

if (this.picPreview.Image != null) 
{ 
    this.picPreview.Image.Dispose(); 
    this.picPreview.Image = null; 
} 
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 
this.picPreview.Image = System.Drawing.Image.FromStream(fs); 

लेकिन इससे कोई फर्क नहीं पड़ता कि मैं छवि पर क्या करता हूं। मैंने फॉर्म को रीफ्रेश करने का प्रयास किया है, पिक्चरबॉक्स नियंत्रण को रीफ्रेश कर रहा है, इसकी दृश्यमान संपत्ति को दृश्यमान करने के लिए सेट किया है, कुछ भी मदद नहीं करता है।

मैं एक अलग रूप बनाता हूं जिसमें केवल एक चित्र बॉक्स होता है और छवि स्थान को फॉर्म में पास करता है और स्ट्रीम खोलने की प्रक्रिया दोहराता है और फिर छवि को इस स्थान पर सेट करता है, यह पूरी तरह से काम करता है।

AFAIK को कोई अपवाद नहीं फेंक दिया जा रहा है ... डीबगर सभी अपवादों को तोड़ने के लिए सेट है।

इस व्यवहार का कारण क्या हो सकता है?

किसी भी सलाह की सराहना की जाती है। मेरे पास एक और एप्लीकेशन है जो पृष्ठभूमि पृष्ठभूमि में छवि उत्पादन करता है और यह भी ठीक काम करता है।

शायद जो कुछ मैं करने की कोशिश कर रहा हूं उसके बारे में अधिक पृष्ठभूमि प्रदान करने से मुझे इसके निचले हिस्से तक पहुंचने में मदद मिलेगी। मेरे डेटाग्रिडव्यू में प्रत्येक पंक्ति के लिए एक से तीन स्तंभ हैं जिनमें उनके साथ एक छवि है। मैंने इन सभी छवियों को अग्रिम में बनाया है। ग्रिड के माध्यम से स्क्रॉल करना मुझे चयन चेंज किए गए ईवेंट का उपयोग करके मेरे चित्र बॉक्स में पहले छवि कॉलम की पूर्वावलोकन छवि मिलती है। यह पूरी तरह से काम करता है। मेरे पास कक्ष भी हैं जो छवि फॉर्म के पूर्वावलोकन के साथ एक फॉर्म विंडो दिखाने पर क्लिक करते हैं जो मुख्य रूप पर छवि बनाते हैं। यह पूरी तरह से काम करता है। मैं पंक्तियों को बदल सकता हूं और ग्रिड में सेल्स पर क्लिक कर सकता हूं और सब कुछ काम करता है। असल में मैं एक नई छवि का निर्माण कर रहा हूं जो उपयोगकर्ता अन्य नियंत्रणों पर आधारित है जो डेटाग्रिड से बंधे हैं।

समस्या तब उत्पन्न होती है जब मैं मुख्य रूप में चित्र बॉक्स में छवि को बदलने का प्रयास करता हूं। मैं डेटासोर्स अपडेट कर सकता हूं, और ग्रिड वैल्यू अपडेट देख सकता हूं, लेकिन छवि, जिसे मैं अब तीसरे पक्ष के सॉफ़्टवेयर का उपयोग करके पुन: उत्पन्न करता हूं, जिसे मैं सत्यापित कर सकता हूं डिस्क पर है और अद्यतन होने के बाद देखने योग्य है, बस गायब हो जाता है। एक बार ऐसा होने के बाद, जब तक मैं फॉर्म बंद नहीं करता और फिर से खोलता हूं, तब तक मुझे फॉर्म में चित्र बॉक्स में कोई छवि नहीं मिलती है, और फिर सभी अद्यतन डेटा वहां होता है और सबकुछ फिर से काम करता है। चयन पर कॉल किया जाने वाला कोड छवि को सेट करने के लिए बदल गया है, नई छवि को अपडेट करने के लिए कोड के समान ही है। यह पूरी तरह से तुल्यकालिक है। मैं एक नए नए रूप के साथ खरोंच से शुरू करने के अलावा अन्य विचारों से बाहर चला रहा हूँ।

सभी सुझावों के लिए फिर से धन्यवाद।

मैं शीर्ष से शुरू करूंगा। कुल प्रवाह निम्नानुसार है:

एक ऐसा फॉर्म खोलें जिसमें एक डाटाग्रिड है जो SQL दृश्य से जुड़ा हुआ है। डीजीवी केवल पढ़ने के लिए है, और एक समय में केवल एक पंक्ति का चयन किया जा सकता है। दृश्य ग्रिड के प्रत्येक कॉलम से जुड़े नियंत्रणों के साथ स्वचालित रूप से पॉप्युलेट हो जाता है। इनमें दूसरों के लिए कुछ, comboboxes और चेकबॉक्स के लिए टेक्स्ट बॉक्स शामिल हैं। प्रत्येक पंक्ति में इसके साथ जुड़े चित्रों का एक सेट होता है। जब फॉर्म लोड होता है, तो मैं दृश्य को स्क्रॉल कर सकता हूं और प्रत्येक पंक्ति के लिए फ़ॉर्म पर चित्र बॉक्स में एक नई छवि दिखाई देती है। इन सभी छवियों को pregenerated किया गया है। जब कोई पंक्ति चुनी जाती है, तो पंक्ति के लिए तीन छवियां हो सकती हैं, जिसमें उपयोगकर्ता ने प्रत्येक छवि का पूर्वावलोकन करने के लिए नेविगेशन बटन सक्षम किए हैं।

मैं एक पंक्ति का चयन करता हूं, चयनित पंक्ति में एक या अधिक सेल मानों को बदलने के लिए फ़ॉर्म पर नियंत्रण बदलता हूं।फिर मैंने एक सेव बटन दबाया, जो डेटाबेस और ग्रिड में संबंधित डेटा को अपडेट करता है। मैं फिर इस पंक्ति के लिए छवि (ओं) को अद्यतन करने का प्रयास करता हूं। इस बिंदु पर चित्र बॉक्स गायब हो जाता है और मैं सभी रूपों पर पूर्वावलोकन को खो देता हूं; कोई छवि तब तक प्रकट नहीं होती जब तक कि मैं फॉर्म को बंद और दोबारा खोलता हूं, और जब तक मैं सहेजता हूं तब तक सब ठीक है।

इसे हल करने की कोशिश में मुझे लगता है कि एक बाध्य डीजीवी अपडेट करने से चुनिंदा बदलाव कई बार उठाया जा सकता है। उन मामलों को संभालने के लिए कोड है जहां बाइंडिंग पूर्ण नहीं है, या दृश्य में कुछ भी नहीं चुना गया है। अद्यतन पूर्ण होने तक और छवि (छवियों) पुन: उत्पन्न होने तक चयन किए गए ईवेंट हैंडलर को निलंबित करने के लिए btnSave_Click हैंडलर में कोड भी है। ऐसा करने के बावजूद, भले ही मैंने जिस पंक्ति को अद्यतन किया है, दृश्य में चुना गया है, वास्तव में चयनित पंक्ति (जहां तीर स्थित है, और सभी नियंत्रण क्या प्रदर्शित होते हैं) पहली पंक्ति हमेशा अपडेट के बाद "वर्तमान" पंक्ति होती है। मुझे नहीं पता कि अभी तक इसे कैसे ठीक किया जाए। यहां चयन के लिए कोड बदल गया है और बटन इवेंट हैंडलर को सहेजता है। enter image description here

और कोड SelectionChanged और btn_save ईवेंट हैंडलर्स के लिए:

यहाँ फार्म की एक स्क्रीन शॉट है

/// <summary> 
     /// update the preview on a row selection change 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void dataGridView1_SelectionChanged(object sender, EventArgs e) 
     { 
      if (!BindingComplete) return; 

      DataGridView dgv = (DataGridView)sender; 

      if (!dgv.Focused || dgv.CurrentRow == null) return;   

      // set the pic preview to the current row image(s) 
      // we need the record for the current index 
      DataRowView currentDataRowView = (DataRowView)dgv.CurrentRow.DataBoundItem; 

      if (currentDataRowView == null) return; 

      DataRow currentRow = currentDataRowView.Row; 

      LastSelectedIndex = dgv.SelectedRows[0].Index; 

      Debug.WriteLine("Current row in SelectionChanged: " + currentRow.ItemArray[0].ToString()); 

      bool showBox = false, showProd = false, showWire = false; 
      string box, prod, wire; 

      string pdcProductName = currentRow.ItemArray[0].ToString(); 

      showWire = !string.IsNullOrEmpty(wire = currentRow.ItemArray[7].ToString()); 

      showBox = !string.IsNullOrEmpty(box = currentRow.ItemArray[8].ToString()); 

      showProd = !string.IsNullOrEmpty(prod = currentRow.ItemArray[9].ToString()); 

      // check for wirepath, box, and product. Enable the nav buttons if there is more than 
      // one label for this product. We need to check for LabelFileName being the same for both 
      // box and product, in which case there is one file for both which defaults to box 
      if ((showBox && showProd && prod == box) || showBox) 
      { 
       string targetFile = PreviewImagePath + pdcProductName + "_eBox.png"; 

       if (picPreview.Image != null) 
       { 
        //picPreview.Image.Dispose(); 
        //picPreview.Image = null; 
       } 

       // if the preview image doesn't exist yet use a default image 
       if (!File.Exists(targetFile)) 
       { 
        // make the loading gif invisible 
        this.picLoading.Visible = true; 

        //picPreview.Image = AdminTILE.Properties.Resources.StandardPaper; 
       } 
       else 
       { 
        this.picLoading.Visible = false; 
        Debug.WriteLine("Opening file " + targetFile); 

        FileStream fs = new FileStream(targetFile, FileMode.Open, FileAccess.Read); 
        picPreview.Image = System.Drawing.Image.FromStream(fs); 
        Image imgCopy = (Image)picPreview.Image.Clone(); 
        this.picPreview.Visible = true; 
        fs.Close(); 

        // preview in another frame 
        if (frm.IsDisposed) 
        { 
         frm = new PreviewImage(); 
        } 
        frm.PreviewLabel(imgCopy); 
        frm.Show();     

        //picPreview.ImageLocation = targetFile; 
       } 
      }    
      else if (showProd) 
      { 
       string targetFile = PreviewImagePath + pdcProductName + "_eBox.png"; 

       if (picPreview.Image != null) 
       { 
        picPreview.Image.Dispose(); 
        //picPreview.Image = null; 
       } 

       if (!File.Exists(targetFile)) 
       { 
        // make the loading gif invisible 
        this.picLoading.Visible = true; 
        //picPreview.Image = AdminTILE.Properties.Resources.StandardPaper; 
       } 
       else 
       { 
        this.picLoading.Visible = false; 
        FileStream fs = new FileStream(targetFile, FileMode.Open, FileAccess.Read); 
        picPreview.Image = System.Drawing.Image.FromStream(fs); 
        fs.Close(); 
       } 
      }   

     } 


     /// <summary> 
     /// update the database with the current selections 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void btnSave_Click(object sender, EventArgs e) 
     { 

      if (dataGridView1.SelectedRows.Count == 0) 
      { 
       MessageBox.Show("No record is selected to update"); 
       return; 
      } 

      DialogResult result1 = MessageBox.Show("Saving Label Configuration. Are you sure?", 
       "IMPORTANT!", MessageBoxButtons.YesNoCancel); 

      // update the view 
      if (result1 == DialogResult.Yes) 
      { 

       // we need the record for the current index 
       DataRowView currentDataRowView = (DataRowView)dataGridView1.CurrentRow.DataBoundItem; 
       DataRow currentRow = currentDataRowView.Row;     
       string pdcProductName = currentRow.ItemArray[0].ToString(); 



       Int32 currentIndex = dataGridView1.SelectedRows[0].Index; 

       Debug.WriteLine("Current index in Save:" + currentIndex.ToString()); 

       string AgencyId="", LogoId="", WireId=""; 

       SqlDataAdapter LabeledProductsDataTableAdapter = 
       new SqlDataAdapter("SELECT * FROM LabeledProducts", 
        printConfigTableAdapter.Connection); 

       SqlDataAdapter LogosDataTableAdapter = 
       new SqlDataAdapter("SELECT * FROM Logos", 
        printConfigTableAdapter.Connection); 

       if (vwTILEAdminTableAdapter.Connection.State != ConnectionState.Open) 
       { 
        printConfigTableAdapter.Connection.Open(); 
       } 

       DataTable LogoDataTable = new DataTable(); 
       LogosDataTableAdapter.Fill(LogoDataTable); 

       DataTable LabeledProductsDataTable = new DataTable(); 
       LabeledProductsDataTableAdapter.Fill(LabeledProductsDataTable); 

       StringBuilder sql = new StringBuilder(); 

       // Fill a table with the results of the 
       // data adapter and query the table instead of the database. 
       // An empty LogoDescription maps to an empty filename 
       DataRow dataRow; 

       if (cbAgency.SelectedItem != null) 
       { 
        sql.Append("LogoDescription = '").Append(cbAgency.SelectedItem).Append("'");      
        dataRow = LogoDataTable.Select(sql.ToString())[0]; 
        AgencyId = dataRow.ItemArray[0].ToString(); 

        sql.Clear(); 
       } 

       if (cbPrivateLabel.SelectedItem != null) 
       { 
        sql.Append("LogoDescription = '").Append(cbPrivateLabel.SelectedItem).Append("'"); 
        dataRow = LogoDataTable.Select(sql.ToString())[0]; 
        LogoId = dataRow.ItemArray[0].ToString(); 

        sql.Clear(); 
       } 

       if (cbWire.SelectedItem != null) 
       { 

        sql.Append("LogoDescription = '").Append(cbWire.SelectedItem).Append("'"); 
        dataRow = LogoDataTable.Select(sql.ToString())[0]; 
        WireId = dataRow.ItemArray[0].ToString(); 

        sql.Clear(); 
       } 


       // PdcProductName is the primary key 
       sql.Append(@"UPDATE [dbo].[LabeledProducts] 
        SET [PdcProductName] = @pdcProd 
         ,[LabelProductName] = @lblProd 
         ,[LabelDescription] = @lblDesc 
         ,[Power] = @pwr 
         ,[Fabrication] = 0 
         ,[UL_File_Number] = @ul 
         ,[PrePrintedSerial] = @pps 
         ,[ShowOrderOnLabel] = 0 
         ,[PrivateLabelLogoId] = @plid 
         ,[AgencyImageId] = @aid 
         ,[WireDiagConfigId] = @wid 
         ,[ReleasedForProduction] = @rfp 
        WHERE PdcProductName = '").Append(pdcProductName).Append("'"); 

       using (SqlCommand command = new SqlCommand(sql.ToString(), vwTILEAdminTableAdapter.Connection)) 
       { 
        if (vwTILEAdminTableAdapter.Connection.State != ConnectionState.Open) 
         vwTILEAdminTableAdapter.Connection.Open(); 

        LabeledProductsDataTableAdapter.UpdateCommand = command; 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@pdcProd", txtPdcProdName.Text); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@lblProd", txtLabeledProd.Text); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@lblDesc", txtLabelDesc.Text); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@pwr", txtPower.Text);      
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@ul", txtULFileNumber.Text); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@pps", cbPrePrintedSerial.Checked); 

        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@plid", LogoId); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@aid", AgencyId); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@wid", WireId); 
        LabeledProductsDataTableAdapter.UpdateCommand.Parameters.AddWithValue("@rfp", cbReleased.Checked); 

        //int rowsAffected = LabeledProductsDataTableAdapter.Update(LabeledProductsDataTable); 
        int rowsAffected = command.ExecuteNonQuery(); 

        // The DataViewManager returned by the DefaultViewManager 
        // property allows you to create custom settings for each 
        // DataTable in the DataSet. 
        DataViewManager dsView = this.tILEDataSet.DefaultViewManager; 

        // remove the selectionChanged event handler during updates 
        // every update causes this handler to fire three times!!! 
        this.dataGridView1.SelectionChanged -= new System.EventHandler(this.dataGridView1_SelectionChanged); 


        dataGridView1.DataSource = typeof(TILEDataSet.vwTILEAdminDataTable); 
        this.vwTILEAdminBindingSource.DataSource = typeof(TILEDataSet.vwTILEAdminDataTable); 
        this.vwTILEAdminBindingSource.DataSource = this.tILEDataSet.vwTILEAdmin; 
        this.dataGridView1.DataSource = this.vwTILEAdminBindingSource;      
        vwTILEAdminBindingSource.ResetBindings(false); // false for data change, true for schema change 

        this.vwTILEAdminTableAdapter.Fill(this.tILEDataSet.vwTILEAdmin); 

        // we need to reget the row after the update to pass to preview 
        currentIndex = LastSelectedIndex; 
        DataGridViewRow drv = this.dataGridView1.Rows[currentIndex]; 
        currentRow = ((DataRowView)(drv.DataBoundItem)).Row; 

        // update the preview files 

        UpdatePreviewFiles(currentRow); 


        // try this 
        dataGridView1.ClearSelection(); 
        // this doesn't work 
        dataGridView1.Rows[currentIndex].Selected = true; 


        // reset the selection changed handler once the update is complete 
        this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged); 

       } 

      } 
     } 

अद्यतन करने के बाद प्रपत्र को छोड़कर चित्र बॉक्स चला गया है एक ही लग रहा है , और पहली पंक्ति से डेटा हाइलाइट की गई पंक्ति के बजाय नियंत्रण में दिखाई देता है।

AfterSave

सभी UpdatePreviewFiles करता छवियों अद्यतन के साथ बदलने है। सभी ShowPreview करता है चित्र को चित्र बॉक्स में सेट किया गया है। छवि। यह सब तब तक काम करता है जब तक मैं एक बचत/अद्यतन नहीं करता।

अगर वहाँ कुछ और मैं मुझे पता है प्रदान कर सकते हैं, इस तक भी हल करने के लिए समय ले रहा है, मुझे पता है एक अपेक्षाकृत सरल व्याख्या है।

फिर से धन्यवाद।

+0

आप कहते हैं कि यह एक सरलीकृत संस्करण में ठीक काम करता है। तो, आपको दोनों के बीच मतभेदों को देखना शुरू करना होगा। –

+0

फाइलस्ट्रीम का उपयोग करने के लिए कोई उद्देश्य? – coder

+1

क्या आप स्ट्रीम बंद कर रहे हैं? –

उत्तर

4

करने का प्रयास करें:

this.picPreview.Image = Image.FromFile(imagePath); 
इसके बजाय FileStream साथ चारों ओर खिलवाड़ की

इसके अलावा, आपको this.picPreview.Imagenull को निपटाने के बाद सेट करने की आवश्यकता नहीं है। जब आप निपटान कहते हैं, तो यह सभी संसाधनों को जारी करता है चाहे आप के पास कोई सूचक है या नहीं।

किसी ऑब्जेक्ट को किसी भी संदर्भ (पॉइंटर) को खोने, किसी अन्य चीज़ के लिए शून्य या अन्य सटीक शब्दों में सेट करना - जीसी (कचरा कलेक्टर) को इसके संसाधनों को रिलीज़ करने का कारण बनता है।

निपटान विधि का उपयोग करने से जीसी इसे जारी करने की अनुमति देगा भले ही आपके पास अभी भी इसका संदर्भ हो। (धन्यवाद रोवलैंड शॉ), तो बस इसे Image.FromFile(imagePath) पर फिर से सेट करना ठीक काम करेगा।

पिछली छवि पर संदर्भ खो जाएगा और जीसी यह निपटाने जब यह यह की तरह लगता है (लंबे समय तक नहीं होगा, मैं वादा करता हूँ)।

तो यह योग करने के लिए ऊपर, मैं इस सवाल का जवाब की शुरुआत में एक पंक्ति के साथ कोड के पूरे टुकड़ा जगह सुझाव है।

+0

यह कचरा संग्रह को तुरंत नहीं पहुंचाएगा - यह सिर्फ इसके लिए अनुमति देता है, जब इसे अगली बार कॉल किया जाता है (जो कुछ स्मृति आवंटित करने के बिंदु पर होगा, मान लीजिए कि इसे मैन्युअल रूप से नहीं कहा जाता है) –

+0

@RowlandShaw जानकारी के लिए धन्यवाद! फिक्स्ड :) – SimpleVar

+0

छवि का उपयोग करना। फ्रॉमफाइल कोई फर्क नहीं पड़ता। जब फॉर्म लोड होता है तो छवि वहां होती है, मैं जो भी कर रहा हूं वह इसे जगह में अपडेट कर रहा है। यह एक ही विधि के भीतर से अलग रूप में ठीक प्रस्तुत करता है। मुझे पिक्चरबॉक्स के बीच कोई अंतर नहीं मिला है। लेकिन आपका शुक्रिया। – Gary

संबंधित मुद्दे