In Xojo 2021R2 binary enumerations were introduced. These Enums must be declared in a module and are treated by the compiler as a class. Xojo documentation for Enums can be found at Enumeration – Xojo Documentation.
I’d like to show you how to create an Enum for Days of the Week and demonstrate the use of that by creating a custom segmented button control.
Open Xojo and create a new Desktop Project. Insert a module and give it a name – I called mine Enumerations.
Next, add an enumeration.
Call this Enum DaysOfWeek and make it a binary enum.
Next, fill in the Declarations.
Next, I’m going to add a bunch of Constants to the module, one for each day of the week. This will allow me to localise the control later.
Now I’ll add a convenience method called ToString that will extend the DaysOfWeek Enum.
The code in this method is:
Var SelectedDays() As String Var d As DaysOfWeek d = DaysOfWeek.Sunday If Value.Contains(d) Then SelectedDays.Add(Day1) End If d = DaysOfWeek.Monday If Value.Contains(d) Then SelectedDays.Add(Day2) End If d = DaysOfWeek.Tuesday If Value.Contains(d) Then SelectedDays.Add(Day3) End If d = DaysOfWeek.Wednesday If Value.Contains(d) Then SelectedDays.Add(Day4) End If d = DaysOfWeek.Thursday If Value.Contains(d) Then SelectedDays.Add(Day5) End If d = DaysOfWeek.Friday If Value.Contains(d) Then SelectedDays.Add(Day6) End If d = DaysOfWeek.Saturday If Value.Contains(d) Then SelectedDays.Add(Day7) End If Return String.FromArray(SelectedDays, ", ")
You can see from this code that it is possible to include multiple days in this Enum. The return string might be “Sunday, Monday, Friday” for example.
Create the DaysOfWeek Control by dragging a segmented button from the library to the navigator and naming it DaysOfWeekControl.
Then use the Inspector Behaviour option to customise the control.
Change the default width to 500 and the selection style to 1 for multiple
Unfortunately, we can’t edit the segments here as the control is a textfield, not a textarea and the edit button is missing. But we can edit the source file (you need a license capable of saving the project in text format). Save and close the project, and open the DaysOfWeekControl.xojo_code file in Notepad, search for “One” which will find the initial value of the control.
You can see each segment is separated with “\r” which the IDE translates to <CR>. Replace “One\rTwo” with “#Day1\r#Day2\r#Day3\r#Day4\r#Day5\r#Day6\r#Day7” which will tell the compiler to use the localised Day constants created earlier. Save the code file and reopen the project.
Now we can continue customising the control first adding a computed property Value As DaysOfWeek. In the Get method add this code:
Var Result As DaysOfWeek = 0 ' The default value is set to create an instance of Result For i As Integer = 0 To 6 ' Each Segment in the control If me.SegmentAt(i).Selected Then Var d As DaysOfWeek = 2 ^ i ' Converts the index (i) to the binary number that matches the value of the enum Result = Result Or d ' Adds the selected day to the enum End If Next i Return Result
You’ll notice the first line sets the value of Result to 0, this is important as otherwise the variable will be Nil – remember this is being rendered as a class by the compiler.
In the Set Method place this code:
For i As Integer = 0 To 6 ' Index of each segment Var d As DaysOfWeek = 2 ^ i ' Convert the index (i) to binary me.SegmentAt(i).Selected = value.Contains(d) ' Set the selected state of the button Next i RaiseEvent ValueChanged(value)
This will show the button as pressed or not depending on whether the day is included on the value. Now add an event definition.
Which will raise when a button is pressed, which means we need to handle the pressed event of the control.
Sub Pressed(segmentIndex as integer) Handles Pressed #Pragma Unused segmentIndex RaiseEvent ValueChanged(Value) End Sub
Time to use the control. We want to place a copy of the control onto Window1; we can either drag the control from the Navigator or select it from the Library (it will show in the Project Controls section). I’m also going to add a label to the Window under the DaysofWeek control, name it SelectedDaysLabel and make it the same width as the control (500). This will be where we will show the result of the days selected.
Next, handle the ValueChanged event on the control:
Sub ValueChanged(Value As DaysOfWeek) Handles ValueChanged
SelectedDaysLabel.Text = Value.ToString
End Sub
When we run the project and select some days, we’ll see something similar to the following.
Now to show the power of the binary enum I’m going to add another declaration to the Enumeration “WeekDays” with a value of 62
62 is the total of the values for Monday through Friday. Once we have this, we can add a button to the window and set its “Pressed” event handler to:
Sub Pressed() Handles Pressed
DaysOfWeekControl1.Value = DaysOfWeek.Weekdays
End Sub
Pressing the button will result in:
Taking this further we can add the enum value to the DateTime class by adding another Extension method to the module as below.
Public Function DayOfWeekEnum(Extends Value As DateTime) As DaysOfWeek Var Result As DaysOfWeek = 2 ^ (Value.DayOfWeek - 1) Return Result End Function
We need to subtract 1 from the DayOfWeek property of the passed DateTime object as the days are 1 based not 0 as in the control. To demonstrate how this works I’m going to add a multiline label to the window called SelectedDatesLabel and set that to show which dates over the next week have been selected by updating the ValueChanged handler as below:
Sub ValueChanged(Value As DaysOfWeek) Handles ValueChanged SelectedDaysLabel.Text = Value.ToString SelectedDatesLabel.Text = "" For i As Integer = 1 To 7 ' From tomorrow for a week Var dt As DateTime = DateTime.Now.AddInterval(0, 0, i) If Value.Contains(dt.DayOfWeekEnum) Then SelectedDatesLabel.Text = SelectedDatesLabel.Text + _ dt.ToString(DateTime.FormatStyles.Short, DateTime.FormatStyles.None) _ + EndOfLine End If Next i End Sub
That’s it folks, hope you enjoyed this tutorial.
Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company Axis Direct Ltd which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.