Xamarin Forms 条目中的删除线文本
Strikethrough text in Entry in Xamarin Forms
最近遇到一个业务需求,需要在Xamarin Forms的入口中显示删除线的文字。现在Label中有删除线的Text decoration 属性,但是Entry中没有这样的属性。
现在我们有一个这样的条目,
但我们需要在 sddad 上显示删除线。有一些资源说要使用效果或 Unicode 的删除线字符集。但它不能满足我们的需求。
有谁知道如何实现这一点,以便我们可以通过 属性 绑定将文本更改为带有删除线?
任何帮助将不胜感激。
只要您想在 Xamarin.Forms 中自定义 UI 行为,而这些行为不会通过表单 API 公开,您就需要深入到平台级别。
删除线文本可以使用以下任何一种实现:CustomRenderer
、Effect
、Behaviour
。
下面是一个平台效果的例子,它将贯穿整个文本:
定义效果
在你的跨平台项目中创建一个新的 RoutingEffect
:
using Xamarin.Forms;
namespace StrikethroughEntry.Effects
{
public class StrikethroughEntryEffect : RoutingEffect
{
public StrikethroughEntryEffect()
: base("StrikethroughEntry.Effects.StrikethroughEntryEffect")
{
}
}
}
实施日期 iOS
在您的 iOS 项目的某处创建一个 PlatformEffect
using Foundation;
using StrikethroughEntry.Effects;
using StrikethroughEntry.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(iOSStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]
namespace StrikethroughEntry.iOS
{
public class iOSStrikethroughEntryEffect : PlatformEffect
{
private static NSNumber _strikethroughStyle => new NSNumber((int)NSUnderlineStyle.Single);
private string _originalText;
protected override void OnAttached()
{
var textField = Control as UITextField;
if (textField is null)
return;
_originalText = textField.Text;
var attributedText = new NSMutableAttributedString(textField.Text);
attributedText.AddAttribute(UIStringAttributeKey.StrikethroughStyle, _strikethroughStyle, new NSRange(0, textField.Text.Length));
textField.AttributedText = attributedText;
}
protected override void OnDetached()
{
var textField = Control as UITextField;
if (textField is null)
return;
textField.AttributedText = null;
textField.Text = _originalText;
}
}
}
此示例展示了如何清除不再需要的效果。属性字符串在 iOS 上的工作方式使得将删除线行为扩展到条目的目标部分变得非常容易。也许你只想删除特定的词等
实施日期 Android
在您的 Android 项目的某处创建一个 PlatformEffect
:
using Android.Graphics;
using Android.Widget;
using StrikethroughEntry.Droid;
using StrikethroughEntry.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(AndroidStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]
namespace StrikethroughEntry.Droid
{
public class AndroidStrikethroughEntryEffect : PlatformEffect
{
private PaintFlags _originalFlags;
protected override void OnAttached()
{
var editText = Control as EditText;
if (editText is null)
return;
_originalFlags = editText.PaintFlags;
editText.PaintFlags = PaintFlags.StrikeThruText;
}
protected override void OnDetached()
{
var editText = Control as EditText;
if (editText is null)
return;
editText.PaintFlags = _originalFlags;
}
}
}
如果您想在 Entry
的特定区域添加删除线,则需要更新此实现。
消耗效果
本例将通过xaml:
- 导入效果命名空间:
xmlns:effects="clr-namespace:StrikethroughEntry.Effects"
- 为目标添加效果
Entry
:
<Entry Text="This entry has strikethrough">
<Entry.Effects>
<effects:StrikethroughEntryEffect />
</Entry.Effects>
</Entry>
结果
现在你有一个可爱的 Entry
带有删除线的文本!
Android
iOS
最近遇到一个业务需求,需要在Xamarin Forms的入口中显示删除线的文字。现在Label中有删除线的Text decoration 属性,但是Entry中没有这样的属性。
现在我们有一个这样的条目,
但我们需要在 sddad 上显示删除线。有一些资源说要使用效果或 Unicode 的删除线字符集。但它不能满足我们的需求。 有谁知道如何实现这一点,以便我们可以通过 属性 绑定将文本更改为带有删除线?
任何帮助将不胜感激。
只要您想在 Xamarin.Forms 中自定义 UI 行为,而这些行为不会通过表单 API 公开,您就需要深入到平台级别。
删除线文本可以使用以下任何一种实现:CustomRenderer
、Effect
、Behaviour
。
下面是一个平台效果的例子,它将贯穿整个文本:
定义效果
在你的跨平台项目中创建一个新的 RoutingEffect
:
using Xamarin.Forms;
namespace StrikethroughEntry.Effects
{
public class StrikethroughEntryEffect : RoutingEffect
{
public StrikethroughEntryEffect()
: base("StrikethroughEntry.Effects.StrikethroughEntryEffect")
{
}
}
}
实施日期 iOS
在您的 iOS 项目的某处创建一个 PlatformEffect
using Foundation;
using StrikethroughEntry.Effects;
using StrikethroughEntry.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(iOSStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]
namespace StrikethroughEntry.iOS
{
public class iOSStrikethroughEntryEffect : PlatformEffect
{
private static NSNumber _strikethroughStyle => new NSNumber((int)NSUnderlineStyle.Single);
private string _originalText;
protected override void OnAttached()
{
var textField = Control as UITextField;
if (textField is null)
return;
_originalText = textField.Text;
var attributedText = new NSMutableAttributedString(textField.Text);
attributedText.AddAttribute(UIStringAttributeKey.StrikethroughStyle, _strikethroughStyle, new NSRange(0, textField.Text.Length));
textField.AttributedText = attributedText;
}
protected override void OnDetached()
{
var textField = Control as UITextField;
if (textField is null)
return;
textField.AttributedText = null;
textField.Text = _originalText;
}
}
}
此示例展示了如何清除不再需要的效果。属性字符串在 iOS 上的工作方式使得将删除线行为扩展到条目的目标部分变得非常容易。也许你只想删除特定的词等
实施日期 Android
在您的 Android 项目的某处创建一个 PlatformEffect
:
using Android.Graphics;
using Android.Widget;
using StrikethroughEntry.Droid;
using StrikethroughEntry.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(AndroidStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]
namespace StrikethroughEntry.Droid
{
public class AndroidStrikethroughEntryEffect : PlatformEffect
{
private PaintFlags _originalFlags;
protected override void OnAttached()
{
var editText = Control as EditText;
if (editText is null)
return;
_originalFlags = editText.PaintFlags;
editText.PaintFlags = PaintFlags.StrikeThruText;
}
protected override void OnDetached()
{
var editText = Control as EditText;
if (editText is null)
return;
editText.PaintFlags = _originalFlags;
}
}
}
如果您想在 Entry
的特定区域添加删除线,则需要更新此实现。
消耗效果
本例将通过xaml:
- 导入效果命名空间:
xmlns:effects="clr-namespace:StrikethroughEntry.Effects"
- 为目标添加效果
Entry
:
<Entry Text="This entry has strikethrough">
<Entry.Effects>
<effects:StrikethroughEntryEffect />
</Entry.Effects>
</Entry>
结果
现在你有一个可爱的 Entry
带有删除线的文本!
Android | iOS |
---|---|