Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

8. April 2010 08:50

Hallo,
ich arbeite derzeit an einem simplen Client Addin,
das die Pictures in den Blob - Feldern der Tabelle Item in der Item Card Page über ein WPF User Control
für das jeweilige Item anzeigt.
Als Erweiterung sollte, per Drag und Drop ein Bild auf dem Control abgelegt werden können,
das dann angezeigt wird, und in der Datenbank im betreffendem Feld abgelegt wird.
In der Datei MyPictureBox.xaml.cs (das komplete Projekt ist angehängt)
erreiche ich schonmal die Anzeige des Bildes:

Code:
private void img_Drop(object sender, DragEventArgs e)
        {
            //Einstiegspunkt für Datenübergabe
           
             if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] filename;
                filename = (string[])e.Data.GetData(DataFormats.FileDrop);
                BitmapImage bi2 = new BitmapImage();
                //MessageBox.Show(filename[0]);
                bi2.BeginInit();
                bi2.StreamSource = File.OpenRead(filename[0]);
                bi2.EndInit();
                img.Source = bi2;
            }
        }


Nur wird es so natürlich nicht in der Datenbank gespeichert.
Ich schätze, sofern das überhaupt geht, muss ich Value damit belegen, und zurück geben?!?
Vermutlich hat es was mit den Get/Set - Methoden zu tun.

Code:
        public object Value
        {
            get
            {
                return this._myPicturebox.GetImage();
               
            }
            set
            {
                if (value is byte[])
                {
                    byte[] data = (byte[])value;

                    /// Specifies that the data loads only once so that data cannot load while the the user is drawing.
                    if (data != null && !this._loaded)
                    {
                        this._myPicturebox.SetImage(data);
                        this._loaded = true;
                       
                    }
                }
            }
        }


Nur finde ich kein geeignetes Beispiel, bzw. bin ich mir nicht sicher, ob das überhaupt funktioniert.
Hat jemand eine Idee dazu?

Freundliche Grüße
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

8. April 2010 19:27

Hi,

ich habe mir das Beispiel jetzt nicht runtergeladen, da ich aktuell kein NAV hier auf dem Rechner habe. Vielleicht helfen dir aber die folgenden Links weiter:

http://msdn.microsoft.com/en-us/library/microsoft.dynamics.framework.ui.extensibility.icontroladdinsite.savevalue(v=NAV.60).aspx - Explizites speichern des Wertes in Value
http://msdn.microsoft.com/en-us/library/dd983746(v=NAV.60).aspx - Zeigt an, dass sich Value geändert hat

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

9. April 2010 11:52

Hallo,
danke für die Antwort.
Hab es mal versucht zu implementieren, scheitert aber wohl daran,
dass ich grad noch dabei bin, mein Wissen der neuen Funktionen von NAV 2009 (Client Addins, Webservices) zu erlernen.
Folgendes scheitert auf jeden Fall

Code:
        public interface IControlAddInSite
        {
            void SaveValues();
        }


Weis aber auch nicht, wie ich das dann Aufrufen soll.
Ich hab mal geschaut, ob die Methode in einem der veröffentlichten Beispiele verwendet wird (ich denke die
meisten davon kenne ich), habe aber nichts entsprechendes gefunden.
Hat jemand ein simples Beispiel, oder sonst noch einen Tipp für mich?

Danke für eure Zeit

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

12. April 2010 08:38

Ich empfehle, es erst über HasValueChanged zu implementieren und nur in Ausnahmesituationen dann SaveValue() zu nutzen. Um Aber SaveValue() zu nutzen, musst du in deiner Klasse das Interface IControlAddInSite implementieren.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

13. April 2010 10:15

OK,
ich habe das Interface jetzt wie folgt implementiert (inklusive aller Members, kompilieren lässt sich das ganze schonmal):

Code:
public class PictureViewer : WinFormsControlAddInBase, IObjectControlAddInDefinition, IControlAddInSite


Hier habe ich jetzt die Methode SaveValue(), die wie folgt aussieht:

Code:
        public void SaveValue()
        {
            MyPictureBox _picture = new MyPictureBox();
            Value = _picture.GetImage();

            /*
            BitmapImage bi3 = new BitmapImage();
            //MessageBox.Show(filename[0]);
            bi3.BeginInit();
            bi3.StreamSource = File.OpenRead("C:\\meinBild.bmp");
            bi3.EndInit();
            Value = bi3;
            MessageBox.Show("Erfolgreich hochgeladen");
            */
        }


Aufgerufen wird SaveValue() über das Drop Event:

Code:
        private void img_Drop(object sender, DragEventArgs e)
        {
            //Einstiegspunkt für Datenübergabe
           
             if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] filename;
                filename = (string[])e.Data.GetData(DataFormats.FileDrop);
                bi2.BeginInit();
                bi2.StreamSource = File.OpenRead(filename[0]);
                bi2.EndInit();
                img.Source = bi2;
                //pv.Value = bi2;
                pv.SaveValue();
                //PictureViewer.IControlAddInSite.SaveValues();
            }
        }


Die Methode GetImage() wiederum sieht wie folgt aus:

Code:
        public BitmapImage GetImage()
        {
            return bi2;           
        }


Hätte jetzt erwartet, dass es so oder so ähnlich funktionieren sollte, aber bisher wird nur das Bild angezeigt, nicht aber in der Datenbank gespeichert.
Eine Messagebox in der Methode SaveValue() zeigt zumindest schonmal an, dass der Code durchlaufen wird, ich mache wohl noch etwas falsch.
Hast du noch weitere Tipps für mich.

Danke für deine Zeit.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

13. April 2010 14:09

Ok, ich habe dich ein wenig auf die falsche Fährte geschickt, sorry. Mein Gedächtnis lässt mit zunehmendem Alter nach :)
Das Property Site stellt, abgeleitet von IControlAddInSite bereits die Methode SaveValue() zur Verfügung. Diese überträgt den aktuellen Wert von Value zurück in die Datenbank.

Trotzdem sollte dir die Rückgabe true für die Eigenschaft HasValueChanged duurchaus langen, um das zu erreichen.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

13. April 2010 14:54

Heißt das, ich
müsste nur den Rückgabewert von false auf true ändern,
oder muss dass dann noch irgendwo aufgerufen werden?
Wenn ich nämlich tatsächlich nur den Rückgabewert ändere,
passiert wiederum nichts.

Freundliche Grüße.

Edit:
Verstehe erst gerade was du mit Site meinst. Müsste ich dann einfach nur Site.SaveValue aufrufen?

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

13. April 2010 19:39

ja genau so, einfach savevalue().
Einfach TRUE zurueck Zu geben Haette allerdings auch funktionieren muessen.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

14. April 2010 13:50

Nachdem ich herausgefunden habe, wie ich aus dem RTC heraus
debuggen kann, konnte ich das Problem etwas eingrenzen.
Soweit ich verstehe, wird bei Verwendung von SaveValue() die Set - Methode von Value aufgerufen.
Diese sieht bei mir so aus:

Code:
        public object Value
        {
            get
            {
                //return Value;
                throw new NotImplementedException();
            }
            set
            {
                if (value is byte[])
                {
                    byte[] data = (byte[])value;

                    /// Specifies that the data loads only once so that data cannot load while the the user is drawing.
                    if (data != null && !this._loaded)
                    {
                        this._myPicturebox.SetImage(data);
                        this._loaded = true;     
                    }
                }
                //BitmapImage bmpresult = new BitmapImage();
                //bmpresult = this._myPicturebox.GetImage();
                //byte[] pictureresult = new byte[bmpresult.PixelWidth * bmpresult.PixelHeight * 4];
                //bmpresult.CopyPixels(pictureresult, ((bmpresult.PixelWidth * bmpresult.Format.BitsPerPixel) + 7) / 8, 0);
                //Value = pictureresult;
                //Value = value;               
            }
        }


Da ich hier den Wert von Value nicht befülle, wird dann konsequenterweise auch mein Bild nicht in die Datenbank hochgeladen.
Nur wie stelle ich das an, dass ich innerhalb der Methode Value wiederum veränderen.
Implementiere ich StringControlAddInBase als Basiskklasse dürfte das folgendermaßen aussehen (anhand eines anderen Beispiels):

Code:
    public override string Value
    {
        get
        {
            return base.Value;
        }
        set
        {
            base.Value = value;
            if (this.control != null)
            {
                this.control.Text = value;
                if (File.Exists(Value))
                {
                    control.Image = Image.FromFile(Value);
                    control.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
                    control.MinimumSize = new Size(control.Image.Width, control.Image.Height);
                    control.MaximumSize = new Size(control.Image.Width, control.Image.Height);
                    ImageState = ImageState + 1;
                }
            }
        }
    }

Hier wird in der Get - Methode base.Value zurückgegeben, und in der Set - Methode wird base.Value ein Wert zugewiesen.
Verwende ich allerdings WinFormsControlAddInBase als Basisklasse, kann ich base.Value nicht verwenden (zumindest
funktioniert das bisher nicht). Belege ich nur Value mit einem Wert, entsteht eine Endlosschleife.
Wie kann ich jetzt in der Set - Methode Value so belegen (vermute Mal Value ist der Wert, der zwischen RTC und Addin ausgetauscht wird),
dass ich keine Endlosschleife verursache und das ganze auch zurückschreiben kann?

Noch weitere Ideen?

Freundliche Grüße

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

16. April 2010 08:37

Hi,

ich hab das Thema nicht vergessen, aber bin aktuell etwas unter Druck. Ich kann dir anbieten mir das die Tage nochmal anzusehen und in deinen Code zu schauen. Vielleicht kannst du den aktuellen Stand nochmal hochladen.

HasValueChanged sollte vom RTC ausgewertet werden, so dass eine Rückgabe von true hier zu einem Zurückschreiben in die Db führt.
SaveValue() in der Site schreibt den Wert explizit in die Db zurück. Natürlich muss Value zu den Zeitpunkten den Wert des Bildes haben.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

28. April 2010 15:53

Hi,

ja, ich war in den letzten Wochen auch sehr beschäftigt.
Wär toll wenn du mal Zeit findest dir das anzugucken (habs in der neuen Version nochmal angehangen), ist vermutlich ein banaler Fehler,
ich finde ihn aber einfach nicht.

Es eilt aber auch nicht.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Client Addin: Drag/Drop Bild - Speichern in Blob - Feld

8. Mai 2010 11:17

Hmm, ich hab jetzt ne knappe Stunde drauf geschaut, mir die Struktur angesehen und würde empfehlen, das Projekt nochmal sauber neu zu starten.
Anfangen mit einer eigenständigen Applikation in der das Setzen und Löschen des Bildes funktioniert und der Status (geändert) per Event o.ä. nach außen gegeben wird.
Wenn der Teil steht, dann bau noch den Client Add-In Teil dazu und nutze dort das Event um HasValueChanged zu füttern.