Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.
2009-06-18
To illustrate what I was talking about here, I made a simple list box to show the concept. The picture illustrates what it looks like, and the code follows.
The Module1 module is the console application with the Main method (startup).
The ConsoleControl class is an abstract base for console controls. This class is for now incredible trivial, and I just built it to make this point.
Then, the ListBox class is the “control” itself and the ListBox item is a pair of a Long (the value) and a String (the visible representation).
I might be way out here, but I’d love to have something like this.
Module Module1 Sub Main() 'Create a listbox. Dim Lb As New ListBox() 'Set some properties. Lb.Height = 4 'Add some items Lb.Add(4, "One") Lb.Add(542, "Two") Lb.Add(9, "Three") Lb.Add(10, "Four") Lb.Add(11, "Five") Lb.Add(12, "Six") Lb.Add(13, "Seven") 'Let the user make a selection. Dim Answer As Integer = Lb.Ask() 'Just for testing: Pause to make sure that the console window is restored. Console.ReadLine() 'Write out the answer and pause again. Console.WriteLine(Answer.ToString()) Console.ReadLine() End Sub End Module Public MustInherit Class ConsoleControl Private m_X As Integer Private m_Y As Integer Private mWidth As Integer Private mHeight As Integer Private mBackgroundColor As System.ConsoleColor Private mForegroundColor As System.ConsoleColor Private mHighlightedBackgroundColor As System.ConsoleColor Private mHighlightedForegroundColor As System.ConsoleColor Private mInactiveForegroundColor As System.ConsoleColor Public Sub New() Me.m_X = 1 Me.m_Y = 1 Me.mWidth = 20 Me.mHeight = 10 Me.mBackgroundColor = ConsoleColor.Blue Me.mForegroundColor = ConsoleColor.White Me.mHighlightedBackgroundColor = ConsoleColor.White Me.mHighlightedForegroundColor = ConsoleColor.Blue Me.mInactiveForegroundColor = ConsoleColor.Gray End Sub Public Property X() As Integer Get Return Me.m_X End Get Set(ByVal value As Integer) Me.m_X = value End Set End Property Public Property Y() As Integer Get Return Me.m_Y End Get Set(ByVal value As Integer) Me.m_Y = value End Set End Property Public Property Width() As Integer Get Return Me.mWidth End Get Set(ByVal value As Integer) Me.mWidth = value End Set End Property Public Property Height() As Integer Get Return Me.mHeight End Get Set(ByVal value As Integer) Me.mHeight = value End Set End Property Public Property BackgroundColor() As ConsoleColor Get Return Me.mBackgroundColor End Get Set(ByVal value As ConsoleColor) Me.mBackgroundColor = value End Set End Property Public Property ForegroundColor() As ConsoleColor Get Return Me.mForegroundColor End Get Set(ByVal value As ConsoleColor) Me.mForegroundColor = value End Set End Property Public Property HighlightedBackgroundColor() As ConsoleColor Get Return Me.mHighlightedBackgroundColor End Get Set(ByVal value As ConsoleColor) Me.mHighlightedBackgroundColor = value End Set End Property Public Property HighlightedForegroundColor() As ConsoleColor Get Return Me.mHighlightedForegroundColor End Get Set(ByVal value As ConsoleColor) Me.mHighlightedForegroundColor = value End Set End Property Public Property InactiveForegroundColor() As ConsoleColor Get Return Me.mInactiveForegroundColor End Get Set(ByVal value As ConsoleColor) Me.mInactiveForegroundColor = value End Set End Property End Class Public Class ListBox Inherits ConsoleControl Private mItems As List(Of ListBoxItem) Private mViewOffset As Integer Private mSelectedIndex As Integer Private mSpacer As String = Nothing Public Sub New() MyBase.New() Me.mItems = New List(Of ListBoxItem)() Me.mSelectedIndex = -1 Me.mViewOffset = 0 End Sub Friend ReadOnly Property Items() As List(Of ListBoxItem) Get Return Me.mItems End Get End Property Public Function Add(ByVal Value As Integer, ByVal DisplayText As String) As Integer Dim Item As New ListBoxItem(Me, Value, DisplayText) Item.Index = mItems.Count mItems.Add(Item) Return Item.Index End Function Public Property SelectedIndex() As Integer Get Return Me.mSelectedIndex End Get Friend Set(ByVal value As Integer) Me.mSelectedIndex = value End Set End Property Public Function Ask() As Integer Return Me.Ask(0) End Function Public Function Ask(ByVal DefaultValue As Integer) As Integer If Me.mItems.Count > 0 Then Me.mSpacer = Space(Me.Width) Dim CursorVisible As Boolean = Console.CursorVisible Dim FG As ConsoleColor = Console.ForegroundColor Dim BG As ConsoleColor = Console.BackgroundColor Console.CursorVisible = False Me.SelectedIndex = ValueToIndex(DefaultValue) Do Me.DrawRegular() Dim Key As ConsoleKeyInfo = Console.ReadKey(True) If Key.Key = ConsoleKey.Escape Then Me.SelectedIndex = -1 Exit Do ElseIf Key.Key = ConsoleKey.Enter Then Exit Do Else Select Case Key.Key Case ConsoleKey.UpArrow If Me.SelectedIndex = 0 Then Me.SelectedIndex = Me.mItems.Count - 1 Else Me.SelectedIndex -= 1 End If Case ConsoleKey.DownArrow If Me.SelectedIndex < (Me.mItems.Count - 1) Then Me.SelectedIndex += 1 Else Me.SelectedIndex = 0 End If End Select End If Loop Me.DrawDead() Console.CursorVisible = CursorVisible Console.ForegroundColor = FG Console.BackgroundColor = BG Dim CursY As Integer = (Me.Y + Me.Height) If CursY >= Console.WindowHeight Then CursY = Console.WindowHeight - 1 End If Console.CursorTop = CursY Console.CursorLeft = 0 Return Me.mItems(Me.SelectedIndex).Value Else Return -1 End If End Function Private Function ValueToIndex(ByVal Value As Integer) As Integer 'This is only called from the Ask function, and the Ask funktion will only run if mItems.Count>0. No need for extra check. For I As Integer = 0 To Me.mItems.Count - 1 If Me.mItems(I).Value = Value Then Return I End If Next Return 0 End Function Private Sub DrawRegular() 'Make sure that the selection is inside the visible area. If Me.mViewOffset > Me.SelectedIndex Then While Me.mViewOffset > Me.SelectedIndex Me.mViewOffset -= 1 End While ElseIf (Me.mViewOffset + Me.Height) <= Me.SelectedIndex Then While (Me.mViewOffset + Me.Height) <= Me.SelectedIndex Me.mViewOffset += 1 End While End If 'Draw the visible items. For I As Integer = 0 To Me.Height - 1 Dim IndexToDisplay As Integer = I + Me.mViewOffset Console.CursorLeft = Me.X Console.CursorTop = Me.Y + I If IndexToDisplay < Me.mItems.Count Then If Me.mItems(IndexToDisplay).Selected Then Console.ForegroundColor = Me.HighlightedForegroundColor Console.BackgroundColor = Me.HighlightedBackgroundColor Else Console.ForegroundColor = Me.InactiveForegroundColor Console.BackgroundColor = Me.BackgroundColor End If Console.Write(Me.mItems(IndexToDisplay).DisplayString) Else Console.ForegroundColor = Me.InactiveForegroundColor Console.BackgroundColor = Me.BackgroundColor Console.Write(Me.mSpacer) End If Next End Sub Private Sub DrawDead() 'Draw the visible items as inactive. For I As Integer = 0 To Me.Height - 1 Dim IndexToDisplay As Integer = I + Me.mViewOffset Console.CursorLeft = Me.X Console.CursorTop = Me.Y + I If IndexToDisplay < Me.mItems.Count Then If Me.mItems(IndexToDisplay).Selected Then Console.ForegroundColor = Me.ForegroundColor Console.BackgroundColor = Me.BackgroundColor Else Console.ForegroundColor = Me.InactiveForegroundColor Console.BackgroundColor = Me.BackgroundColor End If Console.Write(Me.mItems(IndexToDisplay).DisplayString) Else Console.ForegroundColor = Me.InactiveForegroundColor Console.BackgroundColor = Me.BackgroundColor Console.Write(Me.mSpacer) End If Next End Sub End Class Friend Class ListBoxItem Private mListBox As ListBox Private mValue As Integer Private mText As String Private mIndex As Integer = 0 Private mDisplayString As String = Nothing Friend Sub New(ByVal Owner As ListBox, ByVal Value As Integer, ByVal DisplayText As String) Me.mListBox = Owner Me.mValue = Value Me.mText = DisplayText.Trim() End Sub Public Property Index() As Integer Get Return Me.mIndex End Get Friend Set(ByVal value As Integer) Me.mIndex = value End Set End Property Friend ReadOnly Property OwnerListBox() As ListBox Get Return Me.mListBox End Get End Property Public ReadOnly Property Value() As Integer Get Return Me.mValue End Get End Property Public ReadOnly Property Text() As String Get Return Me.mText End Get End Property Public Property Selected() As Boolean Get Return (Me.OwnerListBox.SelectedIndex = Me.Index) End Get Set(ByVal value As Boolean) If value Then Me.OwnerListBox.SelectedIndex = Me.Index Else Me.OwnerListBox.SelectedIndex = -1 End If End Set End Property Friend ReadOnly Property DisplayString() As String Get If Me.mDisplayString Is Nothing Then 'This code will only run once per item, but it still needs rewriting. Risk for multiple memory reallocations. Me.mDisplayString = " " & Me.Text If Me.mDisplayString.Length > Me.OwnerListBox.Width Then Me.mDisplayString = Me.mDisplayString.Substring(0, Me.OwnerListBox.Width) Else While Me.mDisplayString.Length < Me.OwnerListBox.Width Me.mDisplayString &= " " End While End If End If Return Me.mDisplayString End Get End Property End Class
Categories: Microsoft .NET
Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!
Leave a Reply