dcsimg
Results 1 to 15 of 15

Thread: Enums and boolean logic

  1. #1

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Enums and boolean logic

    im trying to understand the conditional logic in this bit of code that i got from MSDN https://docs.microsoft.com/en-us/dot...tframework-4.8

    Code:
     ' Draws the backgrounds for entire ListView items.
        Private Sub listView1_DrawItem(ByVal sender As Object, _
            ByVal e As DrawListViewItemEventArgs) _
            Handles listView1.DrawItem
    
            If Not (e.State And ListViewItemStates.Selected) = 0 Then
    
                ' Draw the background for a selected item.
                e.Graphics.FillRectangle(Brushes.Maroon, e.Bounds)
                e.DrawFocusRectangle()
    
            Else
    
                ' Draw the background for an unselected item.
                Dim brush As New LinearGradientBrush(e.Bounds, Color.Orange, _
                    Color.Maroon, LinearGradientMode.Horizontal)
                Try
                    e.Graphics.FillRectangle(brush, e.Bounds)
                Finally
                    brush.Dispose()
                End Try
    
            End If
    
            ' Draw the item text for views other than the Details view.
            If Not Me.listView1.View = View.Details Then
                e.DrawText()
            End If
    
        End Sub
    specifically this bit
    Code:
       If Not (e.State And ListViewItemStates.Selected) = 0 Then
    
                ' Draw the background for a selected item.
                e.Graphics.FillRectangle(Brushes.Maroon, e.Bounds)
                e.DrawFocusRectangle()
    
            Else
    
                ' Draw the background for an unselected item.
                Dim brush As New LinearGradientBrush(e.Bounds, Color.Orange, _
                    Color.Maroon, LinearGradientMode.Horizontal)
    the variable "e.State" is an enum of type 'ListViewItemState' so what's the point of adding 'And ListViewItemStates.Selected'? Why not just have
    Code:
    If e.State=ListViewItemStates.Selected
    At first i thought it was to check if 'e.State' was null but on testing it doesn't seem to make any difference.

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,142

    Re: Enums and boolean logic

    Believe it or not that is a different kind of And.

    Rather than being boolean logic, it is reading the bits from the binary representation of a number. You can see an explanation and example of it here:
    https://en.wikipedia.org/wiki/Mask_(...tatus_of_a_bit


    The important thing is that several enums (and it turns out ListViewItemStates is one of them) can represent several different things at the same time, so in this case an item can be Focussed as well as Selected (and it can also have been Cut, ready to paste somewhere else).

    Each of the different things are a "yes or no", so fit nicely in a single binary digit. The actual values of the enum have been set up so that they map to binary digits (so 1,2,4,8,16,etc), which means that you can add them all together and still read them... if you use bit masking.

    If you didn't use bit masking you would need to check against lots of different values (eg: checking if "2" is set would mean checking 2,3,6,7,10,11,...).

    It adds a little complexity for reading/writing values, but greatly reduces storage space in memory and/or on disk.

  3. #3
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,421

    Re: Enums and boolean logic

    Si will probably get in before I do, but (without verifying) the reason for such logic is that e.state must be able to be a combination of states, represented by different bits being set. i.e. that the bit for Selected could be set, but others could be set as well.
    So, by Anding State with Selected you isolate the Selected state from any other simultaneous bits that might also be set in the state. If you And the Selected bitmask with State, and it is 0, then Selected isn't active, even though state itself is not 0.
    Also, if other bits are set in State, then State won't equal Selected even is Selected is true.
    So the code is checking to see if Selected is true, regardless of what else may also be true.

    Of course, I didn't verify that the State parameter works that way, but that would be the reason for that code, so there is a good chance it does.

  4. #4
    New Member
    Join Date
    May 2016
    Location
    Argentina
    Posts
    6

    Re: Enums and boolean logic

    It is a BitMask operation with the AND operator.

    The e.State property can hold one o more values (ex: Selected + Checked + Marked) of ListViewItemStates enum, and the comparision (e.State And ListViewItemStates.Selected) = 0 is to know if the value ListViewItemStates.Selected it is one of them.

    If you make the comparision e.State = ListViewItemStates.Selected only will return true if e.State = 1, but if e.State have another value like 3 (Selected + Grayed) will return false.

    I don't know if i made my self clear enought, but in any case you can google BitMaskAnd.

    Cya.

    PS: Tree guys replying at the same time

  5. #5

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Re: Enums and boolean logic

    Thanks for the very excellent explanations for all three of you. Once explained it seems so obvious I feel like I should have figured it out myself.

    Thanks again

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    34,046

    Re: Enums and boolean logic

    I wouldn't feel too bad about that. Compared to Boolean uses, bitmaps are quite rare, so they are not encountered very often. Makes sense to see an "And" and think Boolean rather than bit manipulation, because 99% of the time, it WILL be a Boolean operation.
    My usual boring signature: Nothing

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,896

    Re: Enums and boolean logic

    I'm not sure whether this has already been said or not but keep in mind that bitwise logic IS Boolean logic but performed on corresponding bits in a pair of binary numbers.

  8. #8

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Re: Enums and boolean logic

    The strange thing is though I've used exactly the same code in an owner drawn listview I'm making and it's not working the same as the sample from MSDN. Every time I add some content to the listview the line
    Code:
     If Not (e.State And ListViewItemStates.Selected) = 0 Then
    is doing the opposite of what it does when I run full code from the MSDN example.

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,896

    Re: Enums and boolean logic

    Are you sure the parentheses are in the right place?

  10. #10
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,421

    Re: Enums and boolean logic

    Well, speaking for myself, I wouldn't write the statement that way myself, because I would have to remember the precedence of the operators and I don't always remember them for the more obscure ones, like "Not".

    So, for instance, is the Not being applied to the left side of the = and the result being compared to 0, or is the Not applying to the result of the equivalence.
    i.e. is it
    Code:
    If (Not (e.State And ListViewItemStates.Selected)) = 0
    
    'or
    If Not (e.State And ListViewItemStates.Selected) = 0)
    In the one case, the Not would be boolean operation on the bits of a number, and in the other case, the Not would be a logical operation on the result of the equivalence operation. That is the distinction that I was given back in the 70s when I was learning "Boolean Algebra" in the Navy. Boolean operations were bitwise operations on two numeric values, and Logical operations, were user code level operations of boolean logic, applied to boolean variables, i.e. values that represented True or False.

    Without checking, I would think the Not should be a boolean operation on the bits of the left side of the equivalence, but in that case, the test seems like if would be flawed.
    Let's say that the Selected bit is set.
    Then (e.State And ListViewItemStates.Selected) would equal Selected, which would be a non-zero value, i.e. there would be one bit set somewhere in the value.
    If you apply Not to that value, then you get a ones complimented version of the number, i.e. all the bits that are 0 are changed to 1, and the bit that was 1 will be changed to 0.
    You end up with a value which is still not equal to 0.
    Comparing that value for equivalence to 0 will return false, so the If condition will be False.

    Now, if the Selected bit is not set, then (e.State And ListViewItemStates.Selected) will be 0.
    If you Not (0), you will get -1 and -1 is not equal to 0, so the equivalence test is again False, and therefore the If condition is again False.

    Since either case ends up with the condition being false, then the check wouldn't have any effect, so if it is working, then the assumption that Not is being applied as a boolean operation on the bits of the number on the left side of the equivalence test would seem to be a bad assumption.

    For the logic to work, the equivalence test must precede the Not operation.

    (e.State And ListViewItemStates.Selected) = 0 will be False if the Selected bit is set, and True if the selected bit is not set. You then Not that logical state, to flip the result to True is the selected bit is set and False if the selected bit is not set.

    So, when I write such code, I make sure I add the parenthesis to ensure that sequence. I have had occasions when you have multiple logic operations on a line, mixed with boolean operations, you may not be doing the logical operations where you think you are.
    Code:
    If Not ((e.State And ListViewItemStates.Selected) = 0) Then
    Last edited by passel; Aug 24th, 2019 at 06:30 AM.

  11. #11

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Re: Enums and boolean logic

    Quote Originally Posted by jmcilhinney View Post
    Are you sure the parentheses are in the right place?
    I think so here's the full sub I'm using.

    Code:
      ' Draws the backgrounds for entire ListView items.
        Private Sub listView1_DrawItem(ByVal sender As Object, ByVal e As DrawListViewItemEventArgs) Handles Me.DrawItem
    
            If Not (e.State And ListViewItemStates.Selected) = 0 Then
                ' Draw the background for a selected item.
                e.Graphics.FillRectangle(Brushes.Maroon, e.Bounds)
                e.DrawFocusRectangle()
            Else
                ' Draw the background for an unselected item.
                e.Graphics.FillRectangle(Brushes.DarkGray, e.Bounds)
            End If
    
            ' Draw the item text for views other than the Details view.
            If Not View = View.Details Then
                e.DrawText()
            End If
    
        End Sub
    heres a link to the project.
    https://1drv.ms/u/s!AviP99DGDbSnqXTm...1ntPY?e=v4b35d

  12. #12

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Re: Enums and boolean logic

    Yeah, i do the same wrapping brackets around logic like that usually. I must be missing something elsewhere in the code. I've posted a link to the project above

  13. #13
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Pointless Forest 38.517,-92.023
    Posts
    9,219

    Re: Enums and boolean logic

    Quote Originally Posted by LucasCain View Post
    I think so here's the full sub I'm using.

    Code:
      ' Draws the backgrounds for entire ListView items.
        Private Sub listView1_DrawItem(ByVal sender As Object, ByVal e As DrawListViewItemEventArgs) Handles Me.DrawItem
    
            If Not (e.State And ListViewItemStates.Selected) = 0 Then
                ' Draw the background for a selected item.
                e.Graphics.FillRectangle(Brushes.Maroon, e.Bounds)
                e.DrawFocusRectangle()
            Else
                ' Draw the background for an unselected item.
                e.Graphics.FillRectangle(Brushes.DarkGray, e.Bounds)
            End If
    
            ' Draw the item text for views other than the Details view.
            If Not View = View.Details Then
                e.DrawText()
            End If
    
        End Sub
    heres a link to the project.
    https://1drv.ms/u/s!AviP99DGDbSnqXTm...1ntPY?e=v4b35d
    Change this
    Code:
    If Not (e.State And ListViewItemStates.Selected) = 0  Then
    To
    Code:
    If (e.State And ListViewItemStates.Checked) = ListViewItemStates.Checked Then
    If you are looking for selected.
    Last edited by dbasnett; Aug 26th, 2019 at 08:33 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  14. #14
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,421

    Re: Enums and boolean logic

    Well, I don't know the reason for it. I don't do User Controls myself, but if you check the state in your code, you'll see that for some reason all your items show up as selected (e.State is equal to Selected) for all your items. I added a Debug.Print statement to see the value of e.State each time the event is triggered.
    So, it isn't a problem with the code checking the state, it is a problem with the state being passed in.
    Code:
        ' Draws the backgrounds for entire ListView items.
        Private Sub listView1_DrawItem(ByVal sender As Object, ByVal e As DrawListViewItemEventArgs) Handles Me.DrawItem
            Debug.Print(e.State.ToString)
            If Not ((e.State And ListViewItemStates.Selected) = 0) Then
    '...
    If I look at the actual object (Me) in a watch window while stopped in the above procedure, and drilled down to the selected property of the Items, they show as False.
    I have no idea why the state value in e would show Selected, when the State property of the Items in the ListView don't show Selected. It works find for a regular Listview, even if I set the OwnerDrawn property. Your situation is more complicated because of the User Control situation, and other extra logic.

    Perhaps start a new project, and see if the OwnerDrawn ListView works as expected when it is part of the form, then again when it is part of a user control.
    Also, when it is part of a panel, and tabpage, etc...
    See if you can find a point where it goes awry.

  15. #15

    Thread Starter
    Member
    Join Date
    Nov 2016
    Location
    UK
    Posts
    42

    Re: Enums and boolean logic

    Quote Originally Posted by passel View Post
    Well, I don't know the reason for it. I don't do User Controls myself, but if you check the state in your code, you'll see that for some reason all your items show up as selected (e.State is equal to Selected) for all your items.
    That's the major confusion I was getting. if you look at the notes on the page from Microsoft they straight up admit there are a few bugs in the code for the wrapped win32 control. I've pretty much given up on trying to work through it all logically. I've pretty much worked out how to work around a few of them and ill have to settle for that.

    Big thanks to everyone for their inputs it's been interesting seeing all the different approaches to getting things working

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width