Laden...

settings verwerfen

Erstellt von ivande vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.326 Views
I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren
settings verwerfen

hallo, ich habe ein setting Objekt in welchen ich in einer Form diverse Programmeinstellungen (z.B. Farben, Fonts) vornehmen kann. nun möchte ich dass beim schliessen des Fensters wenn dies nicht mit OK gemacht wird die Einstellungen /veränderungen am Objekt wieder rückgängig gemacht werden.
ich habe zuerst versucht das Objekt zu klonen - dann hat es probleme gegeben beim Serialisieren des Objektes. nun habe ich es mit dem StartTransaction und RollbackTransaction versucht. Kopie ohne IClonable
leider sind in dem Objekt andere Objekte enthalten und nun bekomme ich die Meldung "Keine geschachtelten Transaktionen erlaubt". wie kann man das Problem am besten lösen?

Gruß Ivan

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

"Keine geschachtelten Transaktionen erlaubt" sollte eigentlich nur auftreten, wenn du für ein und dasselbe Objekt mehrfach StartTransaction aufrufst. Das müsste sich leicht vermeiden lassen.

Mit ein bisschen Aufwand könnte man die Klasse BusinessObject aber sicher auch so ändern, dass sie geschachtelte Transaktionen erlaubt.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

StartTransaction(); wird nur 1mal aufgerufen, zumindest beim Debuggen wenn ich einen Haltepunkt dort setze habe ich bereits beim ersten und einzigen Durchlauf den Fehler. kann es sein dass die Hashtable's Probleme machen?
oder dass mein Transaction-Objekt in der Singelton-Klasse "_mainConfig" instanziert wird...
Gruß & Danke für die Hilfe


// so funktioniert StartTransaction
//public FormZGraphConfig()
//{
//            InitializeComponent();
//            _mainConfig.mySerializationClass.ZGraphProperties.StartTransaction();
//}


//so Fehler: Keine geschachtelten Transaktionen erlaubt.
public FormZGraphConfig()
{
            InitializeComponent();
            _mainConfig.mySerializationClass.StartTransaction();
}

public class SerializationClass : BusinessObject
    {
        private string _wboComPort = "COM1"; 
        private int _wboDataFrameFormat = (int)WboFrameFormat.Wbo20;
        private Size _formGaugeSize = new Size(50, 50);
        private Point _formGaugeLoc = new Point(0, 0);
        private FormWindowState _formGaugeWindowState = new FormWindowState();
        private Hashtable configGauges = new Hashtable();
        private Hashtable configGraphs = new Hashtable();
        private ZGraphProperties zGraphConfig = new ZGraphProperties();

        public SerializationClass() { }

        //public virtual object Clone()
        //{

        //    // Flache Kopie des aktuellen Typs (A oder B) erzeugen.
        //    SerializationClass clone = (SerializationClass)this.MemberwiseClone();

        //    // Um tiefe Kopien muss man sich selbst kümmern.
        //    ((Hashtable)clone.configGraphs) = (Hashtable)this.configGraphs.Clone();

        //    //clone.configGraphs = (Hashtable)this.configGraphs.Clone();
        //    clone.ZGraphConfig = (ZGraphProperties)this.zGraphConfig.Clone();

        //    return clone;
        //}
        //public object Clone()
        //{
        //    return this.MemberwiseClone();
        //}


        public ZGraphProperties ZGraphConfig
        {
            get { return zGraphConfig; }
            set { zGraphConfig = value; }
        }

        public Hashtable ConfigGraphs
        {
            get { return configGraphs; }
            set { configGraphs = value; }
        }
        public void SetConfigGraph(string index, GraphProperties gp)
        {
            if (configGraphs == null)
                CreateConfigGraphs();
            if (configGraphs.ContainsKey(index))
                configGraphs[index] = gp;
            else
                AddConfigGraphs(index);
            configGraphs[index] = gp;
        }

        public GraphProperties GetConfigGraph(string index)
        {
            if (configGraphs == null||ConfigGraphs.Count==0)
                CreateConfigGraphs();
            if (configGraphs.ContainsKey(index))
                return configGraphs[index] as GraphProperties;
            else
                AddConfigGraphs(index);
            return configGraphs[index] as GraphProperties;
        }

        public void CreateConfigGraphs()
        {
            configGraphs = new Hashtable();
            string[] names = Enum.GetNames(typeof(WboDrawValues));
            Array values = Enum.GetValues(typeof(WboDrawValues));
            for (int i = 0; i < names.Length; i++)
            {
                GraphProperties gp = new GraphProperties();
                configGraphs.Add(names[i], gp);
            }
        }

        public void SetDefaultConfigGraphs()
        {
            GraphProperties gp = GetConfigGraph(WboDrawValues.Afr.ToString());
            (configGraphs[WboDrawValues.Afr.ToString()] as GraphProperties).SetGraphProperties
                (WboDrawValues.Afr.ToString(), Color.Green, 10, 16, false);
            (configGraphs[WboDrawValues.T1ADC.ToString()] as GraphProperties).SetGraphProperties
                (WboDrawValues.T1ADC.ToString(), Color.Red, 0, 1000, true);
        }

        public void AddConfigGraphs(string index)
        {
            if (configGraphs == null)
                configGraphs = new Hashtable();
            GraphProperties gp = new GraphProperties();
            configGraphs.Add(index, gp);
        }

        public Hashtable ConfigGauges
        {
            get { return configGauges; }
            set { configGauges = value; }
        }

        public GaugeProperties GetConfigGauge(string index)
        {
            if (configGauges != null && configGauges.ContainsKey(index))
                return configGauges[index]as GaugeProperties;
            else
                AddConfigGauge(index);
            return configGauges[index]as GaugeProperties;
        }

        public void AddConfigGauge(string index)
        {
            if (configGauges == null)
                configGauges = new Hashtable();
            GaugeProperties gp = new GaugeProperties();
            configGauges.Add(index, gp);
        }

        public void SetAllConfigGauges(GaugeProperties ConfigToSet)
        {
            Hashtable newConfigGauges = new Hashtable();
            foreach (DictionaryEntry de in configGauges)
            {
                newConfigGauges.Add(de.Key, ConfigToSet);
            }
            configGauges = newConfigGauges;
        }

        public FormWindowState FormGaugeWindowState
        {
            get { return _formGaugeWindowState; }
            set { _formGaugeWindowState = value; }
        }

        public Size FormGaugeSize
        {
            get { return _formGaugeSize; }
            set { _formGaugeSize = value; }
        }

        public Point FormGaugeLoc
        {
            get { return _formGaugeLoc; }
            set { _formGaugeLoc = value; }
        }

        public string WboComPort
        {
            get { return _wboComPort; }
            set { _wboComPort = value; }
        }

        public int WboDataFrameFormat
        {
            get { return _wboDataFrameFormat; }
            set { _wboDataFrameFormat = value; }
        } 
    }

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

wenn du dir den Code von BusinessClass anschaust, siehst du, dass _listScope auf null initialisiert wird und die Meldung nur kommt, wenn _listScope <> null ist. Da _listScope nur in StartTransaction und erst nach der Abfrage gesetzt wird, kann die Exception nicht auftreten, wenn StartTransaction nur einmal aufgerufen wird.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

vielleicht da ich mein objekt serialisiere und dann wird SerializationClass : BusinessObject deserilalisert.... und _listScope ist deswegen nicht null... kann ich _listScope nach dem deserialiseren so auf null setzen?
Gruß



public void InitBusinessObject()
        {
            _guidTransaction = Guid.Empty;
            _boRoot = null;
            _listScope = null;
            _dictFields = null;
        }

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

du kannst es als [NonSerialized] kennzeichnen.

Ich bin mir aber nicht sicher, ob sich das Serialisieren und das Transaktionieren nicht beißt. Sicherheitshalber solltest du nur serialisieren, wenn alle Transaktionen beendet sind.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

dank [NonSerialized()] kann ich serialiseren. StartTransaction und RollbackTransaction stellen meine Eigenschaften in der SerializationClass wieder her, bis auf die beiden Hashtable's... diese werden mit RollbackTransaction nicht wieder hergestellt, grübelgrübel...

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

statt Hashtable solltest du sowieso besser Dictionary nehmen. Und dass sie nicht richtig wiederhergestellt werden, liegt ganz einfach daran:

Eins konnte ich aber auch nicht lösen. Nur bei Feldern mit Werttypen (Int32) oder Readonly-Typen (z.B. String), wird ja echt der Zustand gesichert. Bei Referenztypen (außer BusinessObjects natürlich) wird nur gesichert, welches Objekt eingetragen war (und beim Rollback dieses Objekt wieder eingetragen). Wenn sich aber der Zustand dieses Objekts geändert hat, kann und wird dieser durch das Rollback nicht wiederhergestellt.

Du müsstest _StartTransaction virtual machen und in SerializationClass so überschreiben, dass du dir in _dictFields ["configGauges"] eine Kopie des von configGauges merkst, analog für configGraphs.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

ok deine Beiträge waren mir wieder eine große Hilfe. aber für heute erst mal feiernabend...

Gruß

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

ich habe die Hashtables mit Dictionary ersetzt und mache einfach so die Transaktion... (zumindest komme ich nun zu meinem gewünschtem Ergebnis.

deine Vorgangsweise habe ich (leider) nicht ganz verstanden...

Du müsstest _StartTransaction virtual machen und in SerializationClass so überschreiben, dass du dir in _dictFields ["configGauges"] eine Kopie des von configGauges merkst, analog für configGraphs.



private Dictionary<string, GraphProperties> _dictGraphs = null;

public void ConfigGraphStartTransaction()
        {
            foreach (KeyValuePair<string, GraphProperties> pair in _dictGraphs)
            {
                pair.Value.StartTransaction();
            }
        }

        public void ConfigGraphRollback()
        {
            foreach (KeyValuePair<string, GraphProperties> pair in _dictGraphs)
            {
                pair.Value.RollbackTransaction();
            }
        }


49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

was hast genau du nicht verstanden? Die Beschreibung ist doch ziemlich eindeutig.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

Hallo herbivore
ja die Beschreibung mag je eindeutig sein, du kennst ja genau die Funktion und den Ablauf von Transaktion&co. ich setze das ganze nur ein und weis nicht wie das funktioniert. bin mit meinen c# kenntnissen leider noch nicht so weit. eine Form erstellen ein paar Buttons positionieren und ein paar Zeilen zu schreiben schaffe ich gerade.
ich hab aber keine Idee StartTransaction so zu überschreiben dass das ganze irgenwie eine Kopie meiner Dictionary erstellt...

Gruß Ivan

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

eine (flache) Kopie eines Dictionaries kannst du mit new Dictionary<...> (configGauges) erstellen.

Und Überschreiben heißt einfach nur eine Methode mit gleicher Signatur, aber override erstellen. Natürlich den Aufruf von base._StartTransaction nicht vergessen.

herbivore

I
ivande Themenstarter:in
68 Beiträge seit 2007
vor 16 Jahren

hallo herbivore, das mit virutal und override und aufruf der Basisklasse müsste so passen (zumindest hoffe ich das... wie ich nun in "_dictFields ["configGauges"] eine Kopie des von configGauges merke" verstehe ich immer noch nicht...
Gruß Ivan



public virtual void _StartTransaction(int iLevel, 
                                        Guid guidTransaction,
                                        Rollback boRoot).... // Deklaration als virual versehen

        public SerializationClass() { } // Konstruktor

        public override void _StartTransaction(int iLevel, Guid guidTransaction, Rollback boRoot)
        {
          //  _dictFields = new Dictionary<FieldInfo, Object>(); // ??? 
            base._StartTransaction(iLevel, guidTransaction, boRoot);
        }

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo ivande,

ja, passt soweit. Du musst natürlich erst base._StartTransaction aufrufen, sonst wird dir ja wieder alles überschrieben.

Wie genau du die Kopie erstellst, hängt davon ab, welche Objekte in configGauges enthalten sind und ob du eine tiefe Kopie erstellen musst oder ob eine flache reicht. In "Zeiger" oder Kopie ging/geht es gerade um quasi den gleichen Fall.

herbivore