所以我正在寻找的是一个代码,它将检查用户是否写了一个特定的单词(Select,From,Where)。如果为true,则该单词的textcolor必须更改(TextChanged事件)。我不知道如何做到这一点,这是可能的。
我正在使用Xamarin.Forms
并在Page.xaml
中使用以下代码:
<Editor x:Name="qEditor"
Text="Input"
TextChanged="Handle_TextChanged"
BackgroundColor="White"
HorizontalOptions="FillAndExpand"
HeightRequest="75"/>
因此,每当有人输入其中一个特定单词时,只有该单词的颜色必须直接变为红色。
Page.xaml.cs
中的代码:
void Handle_TextChanged(object sender, TextChangedEventArgs e)
{
string input = e.NewTextValue;
string[] qInput = input.Split(' ');
//Code here
}
我在Google和Stackoverflow以及found something上看了很多,但它使用的Contains
对我的代码无效。
如果您对我需要更改的内容有任何建议,或者即使我必须更改上述代码的所有内容,请给我一些建议。该项目要求我仅使用C#
和Xamarin.Forms
。
答案 0 :(得分:4)
Xamarin表单不支持开箱即用。
您必须扩展Editor
控件才能添加对格式化文本的支持。这可以通过添加类型FormattedString
的可绑定属性来完成。此控件将通过TextChanged
事件监听文本更改来更新属性(在本例中我使用过Regex
)。
由于FormattedText
将是bindable-property,因此自定义平台呈现器可以检测到更改,并相应地将其呈现为Android中的Spannable
和iOS中的AttributedString
。
public class ExEditor : Editor
{
public static readonly BindableProperty FormattedTextProperty =
BindableProperty.Create(
"FormattedText", typeof(FormattedString), typeof(ExEditor),
defaultValue: default(FormattedString));
public FormattedString FormattedText
{
get { return (FormattedString)GetValue(FormattedTextProperty); }
set { SetValue(FormattedTextProperty, value); }
}
public ExEditor()
{
TextChanged += ExEditor_TextChanged;
}
void ExEditor_TextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(Text))
return;
var pattern = @"\b(SELECT|WHERE|AND|OR)\b";
var words = Regex.Split(Text, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
var formattedString = new FormattedString();
foreach (var word in words)
formattedString.Spans.Add(new Span
{
Text = word,
BackgroundColor = BackgroundColor,
FontSize = FontSize,
FontFamily = FontFamily,
FontAttributes = FontAttributes,
ForegroundColor = Regex.IsMatch(word, pattern, RegexOptions.IgnoreCase) ? Color.Red : TextColor
});
FormattedText = formattedString;
}
}
[assembly: ExportRenderer(typeof(ExEditor), typeof(ExEditorRenderer))]
namespace SampleApp.iOS
{
public class ExEditorRenderer : EditorRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Control == null || Element == null)
return;
UpdateTextOnControl();
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(ExEditor.FormattedText)
|| e.PropertyName == nameof(Editor.FontFamily)
|| e.PropertyName == nameof(Editor.FontSize)
|| e.PropertyName == nameof(Editor.TextColor)
|| e.PropertyName == nameof(Editor.BackgroundColor)
|| e.PropertyName == nameof(Editor.FontAttributes))
{
UpdateTextOnControl();
}
}
void UpdateTextOnControl()
{
var caretPos = Control.GetOffsetFromPosition(Control.BeginningOfDocument, Control.SelectedTextRange.Start);
if (Element is ExEditor formsElement)
if (formsElement.FormattedText != null)
Control.AttributedText = formsElement.FormattedText.ToAttributed(new Font(), Element.TextColor);
var newPosition = Control.GetPosition(Control.BeginningOfDocument, offset: caretPos);
Control.SelectedTextRange = Control.GetTextRange(newPosition, newPosition);
}
}
}
[assembly: ExportRenderer(typeof(ExEditor), typeof(ExEditorRenderer))]
namespace SampleApp.Android
{
public class ExEditorRenderer : EditorRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Control == null || Element == null)
return;
UpdateTextOnControl();
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(ExEditor.FormattedText)
|| e.PropertyName == nameof(Editor.FontFamily)
|| e.PropertyName == nameof(Editor.FontSize)
|| e.PropertyName == nameof(Editor.TextColor)
|| e.PropertyName == nameof(Editor.BackgroundColor)
|| e.PropertyName == nameof(Editor.FontAttributes))
{
UpdateTextOnControl();
}
}
void UpdateTextOnControl()
{
var caretPos = Control.SelectionStart;
if (Element is ExEditor formsElement)
if (formsElement.FormattedText != null)
Control.SetText(formsElement.FormattedText.ToAttributed(new Font(), Element.TextColor, Control),
TextView.BufferType.Spannable);
Control.SetSelection(caretPos);
}
}
}
<!-- make sure to map local prefix to control's namespace -->
<local:ExEditor Text="Select * from Table where text='1' and type='str'"
VerticalOptions="Start" />
答案 1 :(得分:1)
在这种情况下,您可以使用FormattedText
Xamarin.Forms.Label
案例中的例子:
private string[] wordsRed = { "Select", "From", "Where"}; // some examples
private bool isSpecialColor = false;
private Span span;
/// <summary>
/// Handles the text changed.
/// </summary>
/// <param name="sender">Sender.</param>
/// <param name="e">E.</param>
void Handle_TextChanged(object sender, TextChangedEventArgs e)
{
string input = e.NewTextValue;
string[] qInput = input.Split(' ');
CheckInput(qInput);
}
/// <summary>
/// Checks the input.
/// </summary>
/// <param name="qInput">Q input.</param>
private void CheckInput(string[] qInput)
{
// Check if the last typed character is a word separator.
if (input[input.Length-1] == ' ')
{
//
// Loop through the string[] with the words you want to give a color on.
//
for (int i = 0; i < wordsRed.Length; i++)
{
//
// Check on the last word that is typed
//
if (qInput[qInput.Length-1] == wordsRed[i])
{
// Create a span with the word and color the foreground red
span = new Span
{
Text = qInput[qInput.Length-1] + " ",
ForegroundColor = Color.Green,
};
// Add the span to the Label
aLabel.FormattedText.Spans.Add(item: span);
// set boolean true because there is made a span with a red foreground.
isSpecialColor = true;
}
else
{
// Do nothing.
}
}
// Check if the word altready is colored.
if (isSpecialColor)
{
// Set the boolean to false for the next check.
isSpecialColor = false;
}
else
{
// Create span with the word and color it black.
span = new Span
{
Text = qInput[i] + " ",
ForegroundColor = Color.Black,
};
aLabel.FormattedText.Spans.Add(item: span);
}
}
else
{
// Do nothing.
}
}