Toon posts:

[C#] Vreemd probleem, lijkt wel bug????

Pagina: 1
Acties:

Verwijderd

Topicstarter
Goed, ik heb echt een heel vaag probleem, en ik begrijp er helemaal niets van. Het is ook een beetje lastig uit te leggen, maar toch probeer ik het even, omdat ik er zelf niet uit kom.

Ik heb een zelfgemaakte class genaamd Settings en deze class bevat o.a. een ArrayList die op zijn beurt weer SecurityRule classes bevat. Ook die class is zelfgemaakt. Het geheel is serializable.

Nu heb ik een formpje gemaakt genaamd frmRuleProperties (dat frm komt nog van m'n VB tijd, die nog niet zo lang geleden was :)). Dit form heeft twee constructors, en die code van die constructors ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public frmRuleProperties(SecurityRule currentrule)
{
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    rulesupplied = true;
    cmbAppliesTo.Text = currentrule.Section == SecurityRule.Sections.FTPServer ? "FTP Server" : currentrule.Section == SecurityRule.Sections.Management ? "Management" : "Monitor";
    cmbAppliesTo.SelectedIndex = Convert.ToInt32(currentrule.Section);
    cmbAction.Text = currentrule.Action == SecurityRule.Actions.KickUser ? "Kick user" : currentrule.Action == SecurityRule.Actions.BanUser ? "Ban user" : "Ban IP";
    cmbAction.SelectedIndex = Convert.ToInt32(currentrule.Action);
    tempparameters = currentrule.Parameters;
    switch (currentrule.Condition) 
    {
        case SecurityRule.Conditions.Hammer:
            lstCondition.SelectedIndex = 0; break;
        case SecurityRule.Conditions.FailLogin:
            lstCondition.SelectedIndex = 1; break;
        case SecurityRule.Conditions.NoCommands:
            lstCondition.SelectedIndex = 2; break;
        case SecurityRule.Conditions.NoData:
            lstCondition.SelectedIndex = 3; break;
        case SecurityRule.Conditions.FailAuthenticate:
            lstCondition.SelectedIndex = 0; break;
        case SecurityRule.Conditions.DiffVersion:
            lstCondition.SelectedIndex = 1; break;
        case SecurityRule.Conditions.InvalidData:
            lstCondition.SelectedIndex = 2; break;
        case SecurityRule.Conditions.HammerManagement:
            lstCondition.SelectedIndex = 3; break;
        case SecurityRule.Conditions.FailAuthenticateMonitor:
            lstCondition.SelectedIndex = 0; break;
        case SecurityRule.Conditions.HammerMonitor:
            lstCondition.SelectedIndex = 1; break;
    }
    lnkRule.Links.Clear();
    int counter = 0;
    foreach (int param in currentrule.Parameters) 
    {
        if (lnkRule.Text.IndexOf("a number of times") > -1) 
        {
            string newtext = param.ToString() + (param == 1 ? " time" : " times");
            lnkRule.Text = lnkRule.Text.Replace("a number of times", newtext);
            lnkRule.Links.Add(lnkRule.Text.IndexOf(newtext), newtext.Length, counter);
            counter++;
        }
        else if (lnkRule.Text.IndexOf("a number of seconds") > -1) 
        {
        string newtext = param.ToString() + (param == 1 ? " second" : " seconds");
        lnkRule.Text = lnkRule.Text.Replace("a number of seconds", newtext);
        lnkRule.Links.Add(lnkRule.Text.IndexOf(newtext), newtext.Length, counter);
        counter++;
        }
    }
}

public frmRuleProperties() 
{
    InitializeComponent();
}

Nou roep ik vanuit een ander form dit form aan, vanuit een click event van een commandbutton met de text Add. Als er dus op de Add knop gedrukt wordt wordt de tweede constructor gebruikt. Vervolgens kijk ik wat het DialogResult is van het form. Het frmSecurityRule form heeft een public variable van het type SecurityRule. Deze variable lees ik uit vanuit het form waar de Add knop op staat. Tot nu toe gaat alles goed.

Op hetzelfde form als waar de Add knop staat staat ook een Properties knop. Met deze properties knop wordt opnieuw het frmSecurityRule form gebruikt maar nu met de eerste constructor. De code onder deze Properties knop ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
...
int index = Convert.ToInt32(lvwSecurityRules.SelectedItems[0].Tag);
frmRuleProperties existingrule = new frmRuleProperties((Interlink_XP.SecurityRule)ServerSettings.SecurityRules[index]);
DialogResult result = existingrule.ShowDialog(this);
if (result == DialogResult.OK)
{
 <Code voor het afhandelen van de data>
}
existingrule.Dispose();
...

De rest van de code is even niet belangrijk, want verder gebeurt er niet zo veel als de gebruiker op de Cancel knop drukt op het frmSecurityRule form. Maar nu komt het probleem.

Als een gebruiker dus op de Properties knop gedrukt heeft dan krijgt de gebruiker een form wat al helemaal ingevuld is (volgens het eerste code blok) en kan de gebruiker hier een aantal dingen veranderen. Als de gebruiker nu echter op een van de linkjes klinkt en een andere waarde instelt en daarna op de Cancel knop drukt en vervolgens weer de Properties knop gebruikt dan zijn op de een of andere manier de wijzigingen toch opgeslagen, ondanks dat de gebruiker op de Cancel knop drukte. Het vreemde is echter dat nergens in het frmRuleProperties form ook maar iets aan de ServerSettings variable (wat van het type Settings is) veranderd wordt. Nergens wordt dus ook maar een waarde gewijzigt, en toch worden die instellingen op de een of andere manier opgeslagen.

Okeej, het is een beetje vaag, maar ik kan het toch echt niet duidelijker maken. 'k hoop dat iemand begrijpt wat het probleem is :).

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Oftewel om even in het kort samen te vatten:
Geeft existingrule.ShowDialog(this) altijd DialogResult.OK terug :?

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:08
Wat je dus wilt zeggen is dus:

als de gebruiker op de cancel knop drukt, wordt de code in het then - block van het if - statement uitgevoerd, alhoewel dat eigenlijk niet zou mogen , omdat die if er zo uit ziet:
code:
1
2
3
if (form.DialogResult == DialogResult.OK)
{
}

Heb je, in uw properties-form, die annuleren-knop aan de CancelButton property van uw form toegewezen?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Nou, die code binnen het if blok wordt dus daadwerkelijk niet uitgevoerd. Dat is maffe nou juist. En het form returnt ook echt DialogResult.Cancel.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:08
Dan moet je nog wel ergens anders code staan hebben die die instellingen gaat gaan bewaren.

Heb je al eens het ganse project gerebuilt ook?

Al eens met de debugger alles stap voor stap overlopen en kijken waar hij saved enzo?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Jah, ik ben al het hele project door geweest, maar nergens worden die settings volgens mij veranderd. Iemand een idee hoe ik een watch kan toevoegen waardoor het programma breakt op het moment dat er iets veranderd? Die optie zat wel in VB6, maar kan hem nergens terug vinden in VS.NET.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op zaterdag 04 mei 2002 13:58 schreef jmezach het volgende:
Jah, ik ben al het hele project door geweest, maar nergens worden die settings volgens mij veranderd. Iemand een idee hoe ik een watch kan toevoegen waardoor het programma breakt op het moment dat er iets veranderd? Die optie zat wel in VB6, maar kan hem nergens terug vinden in VS.NET.
In de sourcecode ga je op de regel staan waar je wilt stoppen en dan F9

Verwijderd

Topicstarter
Das een breakpoint.

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 08-09 01:06
Ik heb geen ervaring met C#, dus ik ga even uit van Java.

Als Java result == DialogResult.OK evalueert en result is geen primitive type, dan worden referenties vergeleken, dus niet de inhoud van de variabelen.

Als je het vergelijkt met C : de waarde van de pointers wordt met elkaar vergeleken, niet de inhoud van het variabelen.
code:
1
2
3
4
if (result == DialogResult.OK)
{
 <Code voor het afhandelen van de data>
}

Verwijderd

Topicstarter
Maar het probleem zit daar dus niet, want die code wordt dus niet uitgevoerd.

Verwijderd

Topicstarter
Hmmz, ik begrijp er echt helemaal niets van. Ik heb m'n code nog eens regel voor regel doorgelopen. Het enige wat de nieuwe waarde krijgt is de variable int[] tempparameters. Maar de inhoud hiervan wordt nooit terug gestuurd naar de ServerSettings variable, en toch wordt die aangepast. Echt heel vreemd is dit :?.

Verwijderd

Topicstarter
Hmmz, ik ben nog eens goed op zoek geweest naar de oorzaak van dit probleem en ik kwam op het volgende uit.

Binnen het form frmRuleProperties heb ik een int[] tempparameters gedeclareerd. In de constructor van het frmRuleProperties form wordt de waarde van die variable de waarde van de Parameters property van de currentrule variable (zie de constructor in de eerste post).

Wat blijkt nu. In de lnkRule_LinkClicked procedure wordt een nieuw form gemaakt waarop de gebruiker een waarde kan invullen. Deze waarde wordt vervolgens weer in de lnkRule_LinkClicked procedure verwerkt. Daar staat het volgende in:
code:
1
tempparameters[Convert.ToInt32(e.Link.LinkData)] = newvalue.newvalue;

Hierbij is newvalue een instance van het frmRuleParameter form en die bevat weer een public int newvalue waarin de geselecteerde waarde komt te staan op het moment dat de gebruiker op Ok klikt op dat form. Maar wat blijkt nu, als deze code uitgevoerd wordt veranderd ook m'n ServerSettings class. Het lijkt wel alsof die integer array en de Parameters property van de SecurityRule class indezelfde geheugenruimte zitten of zo, maar dat lijkt mij toch heel erg sterk. Maar toch veranderd hij de waarde. Dit wordt echt steeds vager.
Pagina: 1