'---------------------------------------------------------------------------- ' EgalTech 2014-2015 '---------------------------------------------------------------------------- ' File : EgtTextBox.xaml.vb Data : 23.12.15 Versione : 1 ' Contenuto : TextBox con tastiera e calcolatrice integrate per EgtWPFLib. ' ' Creato da : Emmanuele Sassi ' Modificato da : ' ' Modifiche : ' '---------------------------------------------------------------------------- Imports System.ComponentModel Imports System.Windows.Controls.Primitives Imports EgtUILib Public Class EgtTextBox Inherits TextBox ' Offset per non mostrare la tastiera attaccata alla TextboxBase Private Const OFFSET = 3 ' Riferimento alla funzione che abilita/disabilita le scene Public Shared m_refScenesIsEnabled As Action(Of Boolean) = Nothing ' Riferimento al PopUp ed alla Keyboard, usati nel caso in cui la tastiera sia attiva Private WithEvents m_KeyboardPopUp As EgtPopup = Nothing Private WithEvents m_Keyboard As EgtWPFLib.EgtKeyboard = Nothing ' Riferimento al PopUp ed alla calcolatrice, usati nel caso in cui la calcolatrice sia attiva Private WithEvents m_CalculatorPopUp As EgtPopup = Nothing Private WithEvents m_Calculator As EgtWPFLib.EgtCalculator = Nothing ' Riferimento alla finestra in cui si trova la EgtTxBx Private m_Owner As Window = Nothing ' Flag per inibire tastiere Private Shared m_bEnableKeybCalc As Boolean = True Public Shared Property EnableKeybCalc As Boolean Get Return m_bEnableKeybCalc End Get Set(value As Boolean) m_bEnableKeybCalc = value End Set End Property ' Flag che segnala se la tastiera è stata appena aperta Private Shared m_bKeyboardFirstOpen As Boolean = True ' Flag che segnala se la calcolatrice è stata appena aperta Private Shared m_bCalculatorFirstOpen As Boolean = True 'Flag che segnala di non aprire la calcolatrice Private m_bActivateCalculator As Boolean = True Public Property ActivateCalculator As Boolean Get Return m_bActivateCalculator End Get Set(value As Boolean) m_bActivateCalculator = value End Set End Property ' Evento che indica la chiusura della tastiera o della calcolatrice Public Event EgtClosed As EventHandler ' Evento che precede l'apertura della calcolatrice Public Event EgtOpening As EventHandler ' Tipo di tastiera da aprire Public Enum KeyboardType As Short Alphanumeric Calculator Null End Enum ' Lato di riferimento per posizionare la tastiera o la calcolatrice Public Enum Positions As Short Top Right Bottom Left End Enum ' DependencyProperty aggiuntive per gestire la tastiera Public Shared ReadOnly KeyboardProperty As DependencyProperty = DependencyProperty.Register("Keyboard", GetType(KeyboardType), GetType(EgtTextBox), New PropertyMetadata(KeyboardType.Null)) Public Property Keyboard As KeyboardType Get Return DirectCast(GetValue(KeyboardProperty), KeyboardType) End Get Set(value As KeyboardType) SetValue(KeyboardProperty, value) End Set End Property Public Shared Function GetKeyboard(element As UIElement) As KeyboardType Return DirectCast(element.GetValue(KeyboardProperty), KeyboardType) End Function Public Shared Sub SetKeyboard(element As UIElement, value As KeyboardType) element.SetValue(KeyboardProperty, value) End Sub ' DependencyProperty aggiuntive per gestire la tastiera Public Shared ReadOnly IsLengthProperty As DependencyProperty = DependencyProperty.Register("IsLength", GetType(Boolean), GetType(EgtTextBox), New PropertyMetadata(True)) Public Property IsLength As Boolean Get Return CBool(GetValue(IsLengthProperty)) End Get Set(value As Boolean) SetValue(IsLengthProperty, value) End Set End Property Public Shared ReadOnly KeyboardPositionProperty As DependencyProperty = DependencyProperty.Register("KeyboardPosition", GetType(Positions), GetType(EgtTextBox), New PropertyMetadata(Positions.Bottom)) Public Property KeyboardPosition As Positions Get Return DirectCast(GetValue(KeyboardPositionProperty), Positions) End Get Set(value As Positions) SetValue(KeyboardPositionProperty, value) End Set End Property Public Shared Function GetKeyboardPosition(element As UIElement) As Positions Return DirectCast(element.GetValue(KeyboardPositionProperty), Positions) End Function Public Shared Sub SetKeyboardPosition(element As UIElement, value As Positions) element.SetValue(KeyboardPositionProperty, value) End Sub Public Shared ReadOnly KeyboardDimensionProperty As DependencyProperty = DependencyProperty.Register("KeyboardDimension", GetType(Double), GetType(EgtTextBox), New PropertyMetadata(500.0)) Public Property KeyboardDimension As Double Get Return DirectCast(GetValue(KeyboardDimensionProperty), Double) End Get Set(value As Double) SetValue(KeyboardDimensionProperty, value) End Set End Property Public Shared Function GetKeyboardDimension(element As UIElement) As Double Return CDbl(element.GetValue(KeyboardDimensionProperty)) End Function Public Shared Sub SetKeyboardDimension(element As UIElement, value As Double) element.SetValue(KeyboardDimensionProperty, value) End Sub ' Evento che, se richiesto, lancia la tastiera quando viene clickata la TextBox Private Sub Me_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseDown OpenKeyboard(sender, CType(e.Source, TextBox)) End Sub Public Sub OpenKeyboard(sender As Object, TxBx As TextBox) If Not IsNothing(m_refScenesIsEnabled) Then m_refScenesIsEnabled(False) If Not m_bEnableKeybCalc Then Dim eCustom As New RoutedEventArgs(PreviewMouseDownEvent, Me) If GetKeyboard(Me) = KeyboardType.Alphanumeric Or GetKeyboard(Me) = KeyboardType.Calculator Then RaiseEvent EgtOpening(sender, eCustom) Return End If Select Case GetKeyboard(Me) Case KeyboardType.Null 'Non devo fare alcunchè Case KeyboardType.Alphanumeric Dim eCustom As New RoutedEventArgs(PreviewMouseDownEvent, Me) RaiseEvent EgtOpening(sender, eCustom) If Not EgtWPFLib.EgtKeyboard.GetbIsActive() Then Dim Owner As FrameworkElement = TxBx While Not TypeOf Owner Is Window If IsNothing(Owner) Then EgtOutLog("Forzata assegnazione finestra principale") Owner = MainWindow Exit While End If Owner = Owner.Parent End While m_Owner = Owner m_KeyboardPopUp = New EgtPopup m_Keyboard = New EgtWPFLib.EgtKeyboard(TxBx, Owner, GetKeyboardDimension(Me)) m_KeyboardPopUp.Child = m_Keyboard m_KeyboardPopUp.PlacementTarget = TxBx m_KeyboardPopUp.Placement = PlacementMode.Custom m_KeyboardPopUp.CustomPopupPlacementCallback = New CustomPopupPlacementCallback(AddressOf placeKeyboardPopup) m_KeyboardPopUp.IsOpen = True End If Case KeyboardType.Calculator Dim eCustom As New RoutedEventArgs(PreviewMouseDownEvent, Me) RaiseEvent EgtOpening(sender, eCustom) If m_bActivateCalculator Then If Not EgtWPFLib.EgtCalculator.GetbIsActive Then Dim Owner As FrameworkElement = TxBx While Not TypeOf Owner Is Window If IsNothing(Owner) Then EgtOutLog("Forzata assegnazione finestra principale") Owner = MainWindow Exit While End If Owner = Owner.Parent End While m_Owner = Owner m_CalculatorPopUp = New EgtPopup m_Calculator = New EgtWPFLib.EgtCalculator(Owner, GetKeyboardDimension(Me), WidthType.PIXEL, TxBx, IsLength) m_CalculatorPopUp.Child = m_Calculator m_CalculatorPopUp.PlacementTarget = TxBx m_CalculatorPopUp.Placement = PlacementMode.Custom m_CalculatorPopUp.CustomPopupPlacementCallback = New CustomPopupPlacementCallback(AddressOf placeCalculatorPopup) m_CalculatorPopUp.IsOpen = True End If m_bActivateCalculator = True Else If Not IsNothing(m_refScenesIsEnabled) Then m_refScenesIsEnabled(True) End If End Select End Sub ' Funzione che permette di posizionare il PopUp con la tastiera Public Function placeKeyboardPopup(ByVal popupSize As Size, ByVal targetSize As Size, ByVal offset As Point) As CustomPopupPlacement() Dim BottomPlacement As New CustomPopupPlacement(New Point(-m_Keyboard.ActualWidth / 2 + Me.ActualWidth / 2, Me.ActualHeight + EgtTextBox.OFFSET), PopupPrimaryAxis.Horizontal) Dim TopPlacement As New CustomPopupPlacement(New Point(-m_Keyboard.ActualWidth / 2 + Me.ActualWidth / 2, -m_Keyboard.ActualHeight + EgtTextBox.OFFSET - 2 * Me.ActualHeight), PopupPrimaryAxis.Horizontal) Dim LeftPlacement As New CustomPopupPlacement(New Point(-m_Keyboard.ActualWidth - EgtTextBox.OFFSET, -m_Keyboard.ActualHeight / 2 + Me.ActualHeight / 2), PopupPrimaryAxis.Vertical) Dim RightPlacement As New CustomPopupPlacement(New Point(Me.ActualWidth + EgtTextBox.OFFSET, -m_Keyboard.ActualHeight / 2 + Me.ActualHeight / 2), PopupPrimaryAxis.Vertical) Dim ttplaces() As CustomPopupPlacement Select Case GetKeyboardPosition(Me) Case Positions.Left ttplaces = {LeftPlacement, RightPlacement, BottomPlacement, TopPlacement} Case Positions.Right ttplaces = {RightPlacement, LeftPlacement, BottomPlacement, TopPlacement} Case Positions.Top ttplaces = {TopPlacement, BottomPlacement, LeftPlacement, RightPlacement} Case Else ttplaces = {BottomPlacement, TopPlacement, LeftPlacement, RightPlacement} End Select Return ttplaces End Function ' Funzione che permette di posizionare il PopUp con la calcolatrice Public Function placeCalculatorPopup(ByVal popupSize As Size, ByVal targetSize As Size, ByVal offset As Point) As CustomPopupPlacement() Dim BottomPlacement As New CustomPopupPlacement(New Point(-m_Calculator.ActualWidth / 2 + Me.ActualWidth / 2, Me.ActualHeight + EgtTextBox.OFFSET), PopupPrimaryAxis.Horizontal) Dim TopPlacement As New CustomPopupPlacement(New Point(-m_Calculator.ActualWidth / 2 + Me.ActualWidth / 2, -m_Calculator.ActualHeight - EgtTextBox.OFFSET), PopupPrimaryAxis.Horizontal) Dim LeftPlacement As New CustomPopupPlacement(New Point(-m_Calculator.ActualWidth - EgtTextBox.OFFSET, -m_Calculator.ActualHeight / 2 + Me.ActualHeight / 2), PopupPrimaryAxis.Vertical) Dim RightPlacement As New CustomPopupPlacement(New Point(Me.ActualWidth + EgtTextBox.OFFSET, -m_Calculator.ActualHeight / 2 + Me.ActualHeight / 2), PopupPrimaryAxis.Vertical) Dim ttplaces() As CustomPopupPlacement Select Case GetKeyboardPosition(Me) Case Positions.Left ttplaces = {LeftPlacement, RightPlacement, BottomPlacement, TopPlacement} Case Positions.Right ttplaces = {RightPlacement, LeftPlacement, BottomPlacement, TopPlacement} Case Positions.Top ttplaces = {TopPlacement, BottomPlacement, LeftPlacement, RightPlacement} Case Else ttplaces = {BottomPlacement, TopPlacement, LeftPlacement, RightPlacement} End Select Return ttplaces End Function ' Evento che permette di selezionare il testo alla prima apertura della tastiera Private Sub Me_PreviewMouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseUp If GetKeyboard(Me) = KeyboardType.Alphanumeric And m_bKeyboardFirstOpen Then Me.Focus() Me.SelectAll() m_bKeyboardFirstOpen = False ElseIf GetKeyboard(Me) = KeyboardType.Calculator And Not IsNothing(m_Calculator) Then m_Calculator.ValueTxBx.Focus() m_Calculator.ValueTxBx.SelectAll() m_bCalculatorFirstOpen = False End If End Sub Private Sub m_Keyboard_EgtClosed(sender As Object, e As EventArgs) Handles m_Keyboard.EgtClosed m_KeyboardPopUp.IsOpen = False m_bKeyboardFirstOpen = True If Not IsNothing(m_refScenesIsEnabled) Then m_refScenesIsEnabled(True) RaiseEvent EgtClosed(sender, e) End Sub Private Sub m_Calculator_EgtClosed(sender As Object, e As EventArgs) Handles m_Calculator.EgtClosed m_CalculatorPopUp.IsOpen = False m_bCalculatorFirstOpen = True If Not IsNothing(m_refScenesIsEnabled) Then m_refScenesIsEnabled(True) RaiseEvent EgtClosed(sender, e) End Sub Private Sub m_KeyboardPopUp_KeyDown(sender As Object, e As Windows.Input.KeyEventArgs) Handles Me.KeyDown If e.Key = Key.Enter Then If Not m_bEnableKeybCalc Then RaiseEvent EgtClosed(sender, e) ElseIf m_KeyboardPopUp.IsOpen AndAlso Not IsNothing(m_Keyboard) Then m_Keyboard.EnterCmd(sender, e) e.Handled = True End If ElseIf e.Key = Key.Escape Then If Not m_bEnableKeybCalc Then ' non faccio alcunché ElseIf m_KeyboardPopUp.IsOpen AndAlso Not IsNothing(m_Keyboard) Then m_Keyboard.ExitCmd(sender, e) e.Handled = True End If End If End Sub ' Evento perdita fuoco, gestito quando non si usa la tastiera Private Sub Me_LostKeyboardFocus(sender As Object, e As Windows.Input.KeyboardFocusChangedEventArgs) Handles Me.LostKeyboardFocus If Not m_bEnableKeybCalc Then If Not IsNothing( m_refScenesIsEnabled) Then m_refScenesIsEnabled( True) RaiseEvent EgtClosed(sender, e) End If End Sub End Class