System.Windows.Forms.CheckState

Posted by Roger Blanchard on 13-May-2009 10:25

I am looping through the NODES of an Infragistics UltraWinTree and the following code never works even if the Nodes:CheckedState is Checked.

IF THIS-OBJECT

:ultraTree1:Nodes[iNode]:CheckedState = System.Windows.Forms.CheckState:CHECKED

If I convert using ToString() with the following it works just fine.

THIS-OBJECT:ultraTree1:Nodes[iNode]:CheckedState:ToString() = "Checked"

Am I missing something?

All Replies

Posted by Peter Judge on 13-May-2009 10:34

rblanchard wrote:

I am looping through the NODES of an Infragistics UltraWinTree and the following code never works even if the Nodes:CheckedState is Checked.

IF THIS-OBJECT

:ultraTree1:Nodes[iNode]:CheckedState = System.Windows.Forms.CheckState:CHECKED

If I convert using ToString() with the following it works just fine.

THIS-OBJECT:ultraTree1:Nodes[iNode]:CheckedState:ToString() = "Checked"

Am I missing something?

The CheckedState is an Enum, and as such you need to do comparisons with the built-in EnumHelper:

Progress.Util.EnumHelper:AreEqual(currentNode:CheckedState, System.Windows.Forms.CheckState:Checked).

I should add that you can, of course, use the ToString() method, and that will work fine, but it removes the strong typing benefits of using the enumeration in the first place. There's also the possibility that the implementation of the ToString() method changes in the future (to say return "CheckedStated: Checked", in which case the code fails. I could also see that ToString() might return a translated string in certain cases.

-- peter

Posted by Roger Blanchard on 13-May-2009 10:40

Thanks Peter.....worked like a charm.

Posted by Admin on 13-May-2009 12:00

I should add that you can, of course, use the ToString() method, and that will work fine, but it removes the strong typing benefits of using the enumeration in the first place.

That's true. But the fact that the EnumHelper does not work in a CASE statement is a real bummer! The ToString() method works in a CASE statement. So when you need to compare an Enum type to more than one value you need to pick one of the two evils:

CASE enumRef:ToString():

  WHEN "CHECKED" THEN ....

  WHEN "UNCHECKED" THEN ...

  WHEN "INDETERMINATE" THEN ...

END CASE.

OR

IF EnumHelper:AreEqual (enumref, System.Windows.Forms.CheckState:Checked) THEN ...

ELSE IF EnumHelper:AreEqual (enumref, System.Windows.Forms.CheckState:Unchecked) THEN ...

ELSE IF EnumHelper:AreEqual (enumref, System.Windows.Forms.CheckState:Indeterminate) THEN ...

Psst.: I pick ToString() with the CASE and EnumHelper when I need to compare to just one option....

There's also the possibility that the implementation of the ToString() method changes in the future (to say return "CheckedStated: Checked", in which case the code fails. I could also see that ToString() might return a translated string in certain cases.

Come on Peter, that is very, very hypothetic. Do you have any reference of that?

Never that less, I guess Progress should implement the comparison of Enum types without the EnumHelper soon!!! Like in C# and .NET (based on operator overloading).

Every new GUI for .NET Developer has fallen accross this, avoided rapid translation of available C# or .NET samples. It's a pain in the ... neck.

Posted by Peter Judge on 13-May-2009 12:47

This works and looks quite pretty too - sure, it's not as good as native, but good enough, I'd say. It probably* performs the same as the nested IFs since each expression must be evaluated until the true one is found, but it's more readable to me.

using Progress.Util.*.
using System.Windows.Forms.*.

def var enumref as System.Windows.Forms.CheckState.

case true:
    when EnumHelper:AreEqual (enumref, CheckState:Checked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Unchecked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Indeterminate) then .
end case.

Come on Peter, that is very, very hypothetic. Do you have any reference of that?

I don't, but I feel it's my duty as an engineer to cover all possible use-cases, even those that are highly unlikely.

Seriously though, I think the strong-typing argument is a good enough argument for not using ToString().

Never that less, I guess Progress should implement the comparison of Enum types without the EnumHelper soon!!! Like in C# and .NET (based on operator overloading).

Every new GUI for .NET Developer has fallen accross this, avoided rapid translation of available C# or .NET samples. It's a pain in the ... neck.

Agreed. I would think - and this is speculative - that that would come if and when enums were implemented in the ABL.

-- peter

* I didn't test the relative performance.

Posted by Admin on 13-May-2009 13:14


using Progress.Util.*.
using System.Windows.Forms.*.

def var enumref as System.Windows.Forms.CheckState.

case true:
    when EnumHelper:AreEqual (enumref, CheckState:Checked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Unchecked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Indeterminate) then .
end case.

I don't consider a good use of a CASE statement at all!

Looking forward for Enums in the ABL then :-)              

Posted by jmls on 16-May-2009 02:31

mikefe wrote:


using Progress.Util.*.
using System.Windows.Forms.*.

def var enumref as System.Windows.Forms.CheckState.

case true:
    when EnumHelper:AreEqual (enumref, CheckState:Checked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Unchecked) then .
    when EnumHelper:AreEqual (enumref, CheckState:Indeterminate) then .
end case.



I don't consider a good use of a CASE statement at all!





Maybe not, but I have been wanting to use a range of values in a case statement for ages ! Expanding a little on the above allows me to do so.

DEF VAR MyVar AS INT.

MyVar = RANDOM(-10,11).

CASE TRUE:

    WHEN MyVar LE 10 AND MyVar GT 1 THEN MESSAGE "case1" MyVar VIEW-AS ALERT-BOX.

    WHEN MyVar LE 1  AND MyVar GT 0 THEN MESSAGE "case2" MyVar VIEW-AS ALERT-BOX.

    WHEN MyVar LE 0                 THEN MESSAGE "case3" MyVar VIEW-AS ALERT-BOX.

    OTHERWISE MESSAGE "case4" MyVar VIEW-AS ALERT-BOX.

END CASE.

This itself could be expanded to allow a "when" to use any 4gl statement as long as it returns a logical

Thanks !

Posted by ChUIMonster on 17-May-2009 02:17

Cute.

But I agree with Mike.

Posted by Admin on 17-May-2009 09:44

That style does not convince me at all. Where do you see the advantage over using a series of

IF expression1 THEN ...

ELSE IF expression2 THEN ...

ELSE IF expression3 THEN ...

ELSE ...

???

Also the doc says:

CASE expression:

   WHEN value1 THEN ...

   WHEN value2 THEN ...

   OTHERWISE ...

END CASE.

Your sample is more like:

CASE value:

    WHEN expression1 THEN ....

    WHEN expression2 THEN ...

    OTHERWISE ....

END.

I don't mind that you can code that way. It's just that I wouldn't do and it will never make it part of our coding standards.

Posted by jmls on 18-May-2009 07:26

Yah! Boo! Boo!

Posted by Thomas Mercer-Hursh on 18-May-2009 11:31

It seems to me that the core advantage of the CASE statement over the IF THEN ELSE IF structure is the clarity which comes from a single expression clearly set out at the top and a very simple and easily read list of conditions.  This use of the CASE statement does not fulfill those advantages.  It isn't so much that it is less clear than an ELSEIF tree, but neither is it substantially better in the way that a CASE statement usually is.

This thread is closed