23/03/13 16:47
amreo
io ho il seguente codice per Win form
e devo convertirlo per WPF.
sono riuscito a convertirlo parzialmente.
(
)
Imports System Imports System.Drawing Public Class SyntaxRTB Inherits System.Windows.Forms.RichTextBox 'La funzione SendMessage serve per inviare dati messaggi 'a una finestra o un dispositivo allo scopo di ottenere 'dati valori od eseguire dati compiti Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer 'Blocca il Refresh della finestra Private Declare Function LockWindowUpdate Lib "user32" _ (ByVal hWnd As Integer) As Integer 'Campo privato che specifica se il meccanismo di syntax 'highlighting è case sensitive oppure no Private _SyntaxHighlight_CaseSensitive As Boolean = False 'La tabella delle parole Public KeyWords As New DataTable Public Property CaseSensitive() As Boolean Get Return _SyntaxHighlight_CaseSensitive End Get Set(ByVal Value As Boolean) _SyntaxHighlight_CaseSensitive = Value End Set End Property 'Contiene costanti usate nell'inviare messaggi all'API 'di windows Private Enum EditMessages LineIndex = 187 LineFromChar = 201 GetFirstVisibleLine = 206 CharFromPos = 215 PosFromChar = 1062 End Enum 'OnTextChanged è una procedura privata che ha il compito 'di generare l'evento TextChanged: prima di farlo, colora il 'testo, ma in questo caso l'evento non viene più generato Protected Overrides Sub OnTextChanged(ByVal e As EventArgs) ColorVisibleLines() End Sub 'Colora tutta la RichTextBox Public Sub ColorRtb() Dim FirstVisibleChar As Integer Dim i As Integer = 0 While i < Me.Lines.Length FirstVisibleChar = GetCharFromLineIndex(i) ColorLineNumber(i, FirstVisibleChar) i += 1 End While End Sub 'Colora solo le linee visibili Public Sub ColorVisibleLines() Dim FirstLine As Integer = FirstVisibleLine() Dim LastLine As Integer = LastVisibleLine() Dim FirstVisibleChar As Integer If (FirstLine = 0) And (LastLine = 0) Then 'Non c'è testo Exit Sub Else While FirstLine < LastLine FirstVisibleChar = GetCharFromLineIndex(FirstLine) ColorLineNumber(FirstLine, FirstVisibleChar) FirstLine += 1 End While End If End Sub 'Colora una linea all'indice LineIndex, a partire dal carattere 'lStart Public Sub ColorLineNumber(ByVal LineIndex As Integer, _ ByVal lStart As Integer) Dim i As Integer = 0 Dim SelectionAt As Integer = Me.SelectionStart Dim MyRow As DataRow Dim Line() As String, MyI As Integer, MyStr As String 'Blocca il refresh LockWindowUpdate(Me.Handle.ToInt32) MyI = lStart If CaseSensitive Then Line = Split(Me.Lines(LineIndex).ToString, " ") Else Line = Split(Me.Lines(LineIndex).ToLower, " ") End If For Each MyStr In Line 'Seleziona i primi MyStr.Length caratteri della linea, 'ossia la prima parola Me.SelectionStart = MyI Me.SelectionLength = MyStr.Length 'Se la parola è contenuta in una delle righe If KeyWords.Rows.Contains(MyStr) Then 'Seleziona la riga MyRow = KeyWords.Rows.Find(MyStr) 'Quindi colora la parola prelevando il colore da 'tale riga If (Not CaseSensitive) Or _ (CaseSensitive And MyRow("Word") = MyStr) Then Me.SelectionColor = Color.FromName(MyRow("Color")) End If Else 'Altrimenti lascia il testo in nero Me.SelectionColor = Color.Black End If 'Aumenta l'indice di un fattore pari alla lunghezza 'della parola più uno (uno spazio) MyI += MyStr.Length + 1 Next 'Ripristina la selezione Me.SelectionStart = SelectionAt Me.SelectionLength = 0 'E il colore Me.SelectionColor = Color.Black 'Riprende il refresh LockWindowUpdate(0) End Sub 'Ottiene il primo carattere della linea LineIndex Public Function GetCharFromLineIndex(ByVal LineIndex As Integer) _ As Integer Return SendMessage(Me.Handle, EditMessages.LineIndex, LineIndex, 0) End Function 'Ottiene la prima linea visibile Public Function FirstVisibleLine() As Integer Return SendMessage(Me.Handle, EditMessages.GetFirstVisibleLine, 0, 0) End Function 'Ottiene l'ultima linea visibile Public Function LastVisibleLine() As Integer Dim LastLine As Integer = FirstVisibleLine() + _ (Me.Height / Me.Font.Height) If LastLine > Me.Lines.Length Or LastLine = 0 Then LastLine = Me.Lines.Length End If Return LastLine End Function Public Sub New() Me.AcceptsTab = True 'Carica la colonna Word e Color KeyWords.Columns.Add("Word") KeyWords.PrimaryKey = New DataColumn() {KeyWords.Columns(0)} KeyWords.Columns.Add("Color") 'Aggiunge le keywords del linguaggio SQL all'array 'Quindi le aggiunge una alla volta alla tabella con 'colore rosso End Sub Sub AddSqlWords() Dim MyRow As DataRow Dim arrKeyWords() As String, strKW As String arrKeyWords = New String() {"select", "INSERT IGNORE", "delete", _ "truncate", "from", "where", "into", "inner", "update", _ "outer", "on", "is", "declare", "set", "use", "values", "as", _ "order", "by", "drop", "view", "go", "trigger", "cube", _ "binary", "varbinary", "image", "char", "varchar", "text", _ "datetime", "smalldatetime", "decimal", "numeric", "float", _ "real", "bigint", "int", "smallint", "tinyint", "money", _ "smallmoney", "bit", "cursor", "timestamp", "uniqueidentifier", _ "sql_variant", "table", "nchar", "nvarchar", "ntext", "left", _ "right", "like", "and", "all", "in", "null", "join", "not", "or"} For Each strKW In arrKeyWords MyRow = KeyWords.NewRow() MyRow("Word") = strKW MyRow("Color") = Color.LightCoral.Name KeyWords.Rows.Add(MyRow) Next End Sub End Class
e devo convertirlo per WPF.
sono riuscito a convertirlo parzialmente.
(
Public Class CustomControl1 Inherits Control Shared Sub New() End Sub End Class Public Class SyntaxRTB Inherits Controls.RichTextBox 'La funzione SendMessage serve per inviare dati messaggi 'a una finestra o un dispositivo allo scopo di ottenere 'dati valori od eseguire dati compiti Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer 'Blocca il Refresh della finestra Private Declare Function LockWindowUpdate Lib "user32" _ (ByVal hWnd As Integer) As Integer 'Campo privato che specifica se il meccanismo di syntax 'highlighting è case sensitive oppure no Private _SyntaxHighlight_CaseSensitive As Boolean = False 'La tabella delle parole Public KeyWords As New DataTable '***** Primo dubbio: sostituire DataTable in Data.DataTable Public Property CaseSensitive() As Boolean Get Return _SyntaxHighlight_CaseSensitive End Get Set(ByVal Value As Boolean) _SyntaxHighlight_CaseSensitive = Value End Set End Property 'Contiene costanti usate nell'inviare messaggi all'API 'di windows Private Enum EditMessages LineIndex = 187 LineFromChar = 201 GetFirstVisibleLine = 206 CharFromPos = 215 PosFromChar = 1062 End Enum 'OnTextChanged è una procedura privata che ha il compito 'di generare l'evento TextChanged: prima di farlo, colora il 'testo, ma in questo caso l'evento non viene più generato Protected Overrides Sub OnTextChanged(e As System.Windows.Controls.TextChangedEventArgs) ColorVisibleLines() End Sub 'Colora tutta la RichTextBox Public Sub ColorRtb() Dim FirstVisibleChar As Integer Dim i As Integer = 0 While i < Me.Lines.Length '************ Me.Lines non esiste in WPF: qual' è il suo equivalente in WPF FirstVisibleChar = GetCharFromLineIndex(i) ColorLineNumber(i, FirstVisibleChar) i += 1 End While End Sub 'Colora solo le linee visibili Public Sub ColorVisibleLines() Dim FirstLine As Integer = FirstVisibleLine() Dim LastLine As Integer = LastVisibleLine() Dim FirstVisibleChar As Integer If (FirstLine = 0) And (LastLine = 0) Then 'Non c'è testo Exit Sub Else While FirstLine < LastLine FirstVisibleChar = GetCharFromLineIndex(FirstLine) ColorLineNumber(FirstLine, FirstVisibleChar) FirstLine += 1 End While End If End Sub 'Colora una linea all'indice LineIndex, a partire dal carattere 'lStart Public Sub ColorLineNumber(ByVal LineIndex As Integer, _ ByVal lStart As Integer) Dim i As Integer = 0 Dim SelectionAt As Integer = Me.SelectionStart '************ Me.SelectionStart non esiste in WPF: qual' è il suo equivalente in WPF? Dim MyRow As DataRow '************ Neanche DataRow Dim Line() As String, MyI As Integer, MyStr As String 'Blocca il refresh LockWindowUpdate(Me.Handle.ToInt32) '************ Me.Handle MyI = lStart If CaseSensitive Then Line = Split(Me.Lines(LineIndex).ToString, " ") '************ Me.Lines Else Line = Split(Me.Lines(LineIndex).ToLower, " ") '************ Me.Lines End If For Each MyStr In Line 'Seleziona i primi MyStr.Length caratteri della linea, 'ossia la prima parola Me.SelectionStart = MyI '************ Me.SelectionStart Me.SelectionLength = MyStr.Length '************ Me.SelectionLenght 'Se la parola è contenuta in una delle righe If KeyWords.Rows.Contains(MyStr) Then 'Seleziona la riga MyRow = KeyWords.Rows.Find(MyStr) 'Quindi colora la parola prelevando il colore da 'tale riga If (Not CaseSensitive) Or _ (CaseSensitive And MyRow("Word") = MyStr) Then Me.SelectionColor = Color.FromName(MyRow("Color")) '************ Me.SelectionColor e Color.FromName End If Else 'Altrimenti lascia il testo in nero Me.SelectionColor = Color.Black '************ Me.SelectionColor e Color.Black End If 'Aumenta l'indice di un fattore pari alla lunghezza 'della parola più uno (uno spazio) MyI += MyStr.Length + 1 Next 'Ripristina la selezione Me.SelectionStart = SelectionAt '************ Me.SelectionStart Me.SelectionLength = 0 '************ Me.SelectionLenght 'E il colore Me.SelectionColor = Color.Black '************ Me.SelectionColor e Color.Black 'Riprende il refresh LockWindowUpdate(0) End Sub 'Ottiene il primo carattere della linea LineIndex Public Function GetCharFromLineIndex(ByVal LineIndex As Integer) _ As Integer Return SendMessage(Me.Handle, EditMessages.LineIndex, LineIndex, 0) '************ Me.Handle End Function 'Ottiene la prima linea visibile Public Function FirstVisibleLine() As Integer Return SendMessage(Me.Handle, EditMessages.GetFirstVisibleLine, 0, 0) '************ Me.Handle End Function 'Ottiene l'ultima linea visibile Public Function LastVisibleLine() As Integer Dim LastLine As Integer = FirstVisibleLine() + _ (Me.Height / Me.Font.Height) '************ Me.Font If LastLine > Me.Lines.Length Or LastLine = 0 Then '************ Me.Lines LastLine = Me.Lines.Length '************ Me.Lines End If Return LastLine End Function Public Sub New() 'Questa chiamata OverrideMetadata indica al sistema che l'elemento fornisce uno stile diverso dalla relativa classe base. 'Questo stile viene definito in Themes\Generic.xaml DefaultStyleKeyProperty.OverrideMetadata(GetType(CustomControl1), New FrameworkPropertyMetadata(GetType(CustomControl1))) Me.AcceptsTab = True 'Carica la colonna Word e Color KeyWords.Columns.Add("Word") KeyWords.PrimaryKey = New DataColumn() {KeyWords.Columns(0)} '************ DataColumn KeyWords.Columns.Add("Color") 'Aggiunge le keywords del linguaggio SQL all'array 'Quindi le aggiunge una alla volta alla tabella con 'colore rosso End Sub Sub AddSqlWords() Dim MyRow As DataRow '************ DataRow Dim arrKeyWords() As String, strKW As String arrKeyWords = New String() {"select", "INSERT IGNORE", "delete", _ "truncate", "from", "where", "into", "inner", "update", _ "outer", "on", "is", "declare", "set", "use", "values", "as", _ "order", "by", "drop", "view", "go", "trigger", "cube", _ "binary", "varbinary", "image", "char", "varchar", "text", _ "datetime", "smalldatetime", "decimal", "numeric", "float", _ "real", "bigint", "int", "smallint", "tinyint", "money", _ "smallmoney", "bit", "cursor", "timestamp", "uniqueidentifier", _ "sql_variant", "table", "nchar", "nvarchar", "ntext", "left", _ "right", "like", "and", "all", "in", "null", "join", "not", "or"} For Each strKW In arrKeyWords MyRow = KeyWords.NewRow() MyRow("Word") = strKW MyRow("Color") = Color.LightCoral.Name '************ Color.LightCoral.Name KeyWords.Rows.Add(MyRow) Next End Sub End Class
)
aaa