xamarin - 我需要阻止 XamarinForms 上日期选择器中的粘贴功能

标签 xamarin xamarin.forms xamarin.ios xamarin.android

在我正在构建的解决方案中,我有一个运行良好的日期选择器。但是,如果用户按下触摸并粘贴某些内容,它将覆盖日期。

当用户粘贴时,不会引发 OnElementChangedOnElementPropertyChanged 甚至 INotifyPropertyChanged 事件。我也找不到阻止粘贴功能的选项。 (正常选择日期时,事件被调用。)

这种情况发生在 iOS 和 Android 中。有人能帮我吗?我陷入困境,我的研究对我没有多大帮助。

最佳答案

iOS平台

DatePicker 之所以如此,是因为它在底层是通过 UITextField 实现的。 为了避免编辑 UITextField,您必须为其分配一个从 ShouldChangeCharacters 方法返回 false 的委托(delegate)。

完整的解决方案如下:

在共享项目中声明 DatePicker 的子级:

public class ExtendedDatePicker : DatePicker
{
}

在iOS项目中声明相应的渲染器:

[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]  
...    

public class ExtendedDatePickerRenderer : DatePickerRenderer  
{  
    private UneditableUITextFieldDelegate _delegate = new UneditableUITextFieldDelegate();  

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)  
    {
        base.OnElementChanged(e);

        Control.Delegate = _delegate;
    }
}

实现UneditableUITextFieldDelegate:

public class UneditableUITextFieldDelegate : NSObject, IUITextFieldDelegate
{
    [Export("textField:shouldChangeCharactersInRange:replacementString:")]
    public bool ShouldChangeCharacters(UITextField textField, NSRange range, string replacementString) =>
        false;
}

这不会阻止显示“复制”/“粘贴”菜单,但按下它们后 DatePicker 值不会更改。

Android平台

Android 上 DatePicker 的底层 UI 元素是 EditText

我在 native Android 中发布了文章,解释如何操作 EditText 的上下文菜单。和 Xamarin.Forms 。你可以在那里得到总体的想法。

我无法在 DatePicker 上进行长按来查看问题,因此我只能猜测正确的修复方法,但是与此类似的渲染器应该完全禁用所选内容的上下文菜单文本以及用户点击光标时的粘贴选项:

[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
...

public class ExtendedDatePickerRenderer : DatePickerRenderer
{
    public ExtendedDatePickerRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
    {
        base.OnElementChanged(e);

        Control.CustomSelectionActionModeCallback = new CustomSelectionActionModeCallback();
        Control.CustomInsertionActionModeCallback = new CustomInsertionActionModeCallback();
    }
}

CustomInsertionActionModeCallbackCustomInsertionActionModeCallback 将从 OnCreateActionMode 返回 false 并阻止菜单出现。

public class CustomInsertionActionModeCallback : Java.Lang.Object, ActionMode.ICallback
{
    public bool OnCreateActionMode(ActionMode mode, IMenu menu) => false;

    public bool OnActionItemClicked(ActionMode m, IMenuItem i) => false;

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu) => true;

    public void OnDestroyActionMode(ActionMode mode) { }
}

public class CustomSelectionActionModeCallback : Java.Lang.Object, ActionMode.ICallback
{
    public bool OnActionItemClicked(ActionMode m, IMenuItem i) => false;

    public bool OnCreateActionMode(ActionMode mode, IMenu menu) => false;

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu) => true;

    public void OnDestroyActionMode(ActionMode mode) { }
}

=======
更新:这个问题启发我创建了一个 article用一些解释和细节扩展这个答案。

关于xamarin - 我需要阻止 XamarinForms 上日期选择器中的粘贴功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52652007/

相关文章:

iphone - 如何使用单触摸向 iPhone 应用程序添加图标?

ios - 在 iOS 10.1 Xamarin(iOS) 中设置 StatusBar 样式的错误

android - 制作视频合并移动应用程序的最佳方法

android - Android平台Xamarin Editor Control中如何去除文本下划线?

xamarin.ios - 自定义 Xamarin.Forms 布局

Xamarin 表格 : Single button that opens a dropdown menu

xamarin - Visual Studio Android 模拟器优化应用程序循环

json - Bad Request -Post 方法 - JSON DateTime 问题

xamarin - 我使用标签作为按钮。如何用圆边边框包围它?

xamarin.ios - MonoDevelop:与 "Content"相比,构建操作 "Resource"是什么?