微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 UWP 中,如何为自定义控件设置自动化 iD?

如何解决在 UWP 中,如何为自定义控件设置自动化 iD?

我在 Xamarin Forms 中创建了一个自定义控件。为了测试,我在表单中使用了自动化 ID 属性,但我无法在检查工具中获取自动化 ID。如果我设置了一个虚拟的本机控件,我可以获得自动属性,但如果我没有设置本机控件,则不会显示自动化 ID。设置一个虚拟的本机控件不是一个好习惯,所以任何人都请帮助如何获取自定义控件的自动化 ID。我在下面附上了我的样本: Sample Link

自定义控件代码片段如下:

class FormsCustomLayout : TemplatedView
{
    public static readonly BindableProperty InputViewProperty =
        BindableProperty.Create(nameof(InputView),typeof(View),typeof(FormsCustomLayout),null,BindingMode.Default,OnInputViewChanged);

    private static void OnInputViewChanged(BindableObject bindable,object oldValue,object newValue)
    {
        (bindable as FormsCustomLayout).OnInputViewChanged(oldValue,newValue);
    }

    private void OnInputViewChanged(object oldValue,object newValue)
    {
        var oldView = (View)oldValue;
        if (oldView != null)
        {
            if (this.contentGrid.Children.Contains(oldView))
            {
                oldView.SizeChanged -= OnInputViewSizeChanged;
                oldView.BindingContext = null;
                this.contentGrid.Children.Remove(oldView);
            }
        }

        var newView = (View)newValue;
        if (newView != null)
        {
            newView.SizeChanged += OnInputViewSizeChanged;
            newView.VerticalOptions = Layoutoptions.CenterandExpand;
            newView.HeightRequest = 60;
             this.contentGrid.Children.Add(newView);
        }
    }

    private void OnInputViewSizeChanged(object sender,EventArgs e)
    {

    }

    public  View InputView
    {
        get { return (View)GetValue(InputViewProperty); }
        set { SetValue(InputViewProperty,value); }
    }

    internal void UpdateText(object text)
    {
        this.Text = (string)text;
    }

    private readonly Grid contentGrid = new Grid();

    public FormsCustomLayout()
    {
        this.ControlTemplate = new ControlTemplate(typeof(StackLayout));
        ((StackLayout)Children[0]).Children.Add(this.contentGrid);
        if (InputView != null)
        {
            this.contentGrid.Children.Add(InputView);
        }
    }

    internal string Text { get; private set; }
}

自定义渲染器代码如下:

类 FormsCustomLayoutRenderer : VieWrenderer { private FormsCustomLayout inputLayout;

    internal string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty,value); }
    }

    internal static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text",typeof(string),typeof(FormsCustomLayoutRenderer),new PropertyMetadata(null,OnTextPropertyChanged));

    private static void OnTextPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        (d as FormsCustomLayoutRenderer).OnTextPropertyChanged();
    }

    private void OnTextPropertyChanged()
    {
        inputLayout?.UpdateText(this.Text);
    }

    private Panel inputVieWrenderer;

    private TextBox nativeTextBox;

    protected override void SetAutomationId(string id)
    {
        if (this.Control == null)
        {
            base.SetAutomationId(id);
        }
        else
        {
            this.SetAutomationPropertiesAutomationId(id);
            this.Control.SetAutomationPropertiesAutomationId(id);
        }
    }

    protected override AutomationPeer OnCreateAutomationPeer()
    {
        if (this.Control == null)
        {
            return new FormsCustomLayoutAutomationPeer(this);
        }

        return new FormsCustomLayoutAutomationPeer(this.Control);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<FormsCustomLayout> e)
    {
        base.OnElementChanged(e);
        var element = e.NewElement;
        if (element != null && element is FormsCustomLayout)
        {

            inputLayout = element as FormsCustomLayout;
            UpdateNativeView(inputLayout.InputView);
        }
        // setting Dummy native control.
       // SetNativeControl(new Grid());
    }

    private void UpdateNativeView(View inputView)
    {
        if (inputView == null)
        {
            return;
        }

        if (Platform.GetRenderer(inputView) == null)
        {
            Platform.SetRenderer(inputView,Platform.CreateRenderer(inputView));
        }

        var renderer = Platform.GetRenderer(inputView);
        inputVieWrenderer = renderer as Panel;
        nativeTextBox = GetNativeTextBox(inputVieWrenderer);
        if (nativeTextBox is FormsTextBox)
        {
            (nativeTextBox as FormsTextBox).BackgroundFocusBrush = new Windows.UI.Xaml.Media.solidColorBrush(Colors.Transparent);
        }

        if (nativeTextBox is TextBox)
        {
            if (nativeTextBox != null)
            {
                nativeTextBox.IsTabStop = inputLayout.IsEnabled;
                SetBinding(TextProperty,new Windows.UI.Xaml.Data.Binding { Source = nativeTextBox,Path = new PropertyPath("Text"),Mode = Windows.UI.Xaml.Data.BindingMode.TwoWay });
            }
        }

        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender,RoutedEventArgs e)
    {
        if (nativeTextBox == null)
        {
            return;
        }
    }

    private TextBox GetNativeTextBox(FrameworkElement frameworkElement)
    {
        TextBox textBox = null;
        int childCount = VisualTreeHelper.GetChildrenCount(frameworkElement);
        for (int i = 0; i < childCount; i++)
        {
            var child = VisualTreeHelper.GetChild(frameworkElement,i);
            if (child is TextBox)
            {
                textBox = child as TextBox;
            }
            else if (child is FrameworkElement innerElement)
            {
                textBox = GetNativeTextBox(innerElement);
            }

            if (textBox != null)
            {
                break;
            }
        }

        return textBox;
    }

    public static void Init()
    {
    }
}

internal class FormsCustomLayoutAutomationPeer : FrameworkElementAutomationPeer
{
    public FormsCustomLayoutAutomationPeer(FrameworkElement owner) : base(owner)
    {
    }

    protected override AutomationControlType GetAutomationControlTypeCore()
    {
        return AutomationControlType.Custom;
    }

    protected override string GetClassNameCore()
    {
        return "FormsCustomLayout";
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。