当鼠标悬停在超链接上时,如何在Xamarin.forms中更改鼠标光标?

uubf1zoe  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(110)

Xamarin.forms 3.3.0 update中,建议通过以下方式创建超链接:

<Label>
    <Label.FormattedText>
        <FormattedString>
            <FormattedString.Spans>
                <Span Text="This app is written in C#, XAML, and native APIs using the" />
                <Span Text=" " />
                <Span Text="Xamarin Platform" FontAttributes="Bold" TextColor="Blue" TextDecorations="Underline">
                    <Span.GestureRecognizers>
                       <TapGestureRecognizer 
                            Command="{Binding TapCommand, Mode=OneWay}"
                            CommandParameter="https://learn.microsoft.com/en-us/xamarin/xamarin-forms/"/>
                     </Span.GestureRecognizers>
                </Span>
                <Span Text="." />
            </FormattedString.Spans>
        </FormattedString>
    </Label.FormattedText>
</Label>

通常,在Windows上,鼠标光标悬停在超链接上时会发生变化。在Xamarin.forms中有没有方法可以得到相同的鼠标路线变化?

uoifb46i

uoifb46i1#

我认为你可以为UWP创建一个自定义渲染器。例如,类似这样的东西:

[assembly: ExportRenderer(typeof(HyperLinkLabel), typeof(HyperLinkLabel_UWP))]
namespace MyApp.UWP.CustomRenders
{
    public class HyperLinkLabel_UWP: LabelRenderer
    {
        private readonly Windows.UI.Core.CoreCursor OrigHandCursor = Window.Current.CoreWindow.PointerCursor;

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

            if (e.OldElement == null)
            {
                Control.PointerExited += Control_PointerExited;
                Control.PointerMoved += Control_PointerMoved;
            }
        }

        private void Control_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
        {
            Windows.UI.Core.CoreCursor handCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 1);
            if (handCursor != null)
                Window.Current.CoreWindow.PointerCursor = handCursor;
        }

        private void Control_PointerExited(object sender,     Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
        {
            if (OrigHandCursor != null)
                Window.Current.CoreWindow.PointerCursor = OrigHandCursor;
        }
    }
}
g0czyy6m

g0czyy6m2#

如果你需要它用于特定的跨度,你可以这样做:
创建一个扩展的span类来将span标记为链接-

public class ExtendedSpan : Span
{
    public static readonly BindableProperty IsLinkProperty =
        BindableProperty.Create(
            nameof(IsLink),
            typeof(bool),
            typeof(ExtendedSpan),
            false,
            BindingMode.OneWay);

    public bool IsLink
    {
        get { return (bool)GetValue(IsLinkProperty); }
        set { SetValue(IsLinkProperty, value); }
    }
}

对于UWP,在渲染器中,使用超链接元素替换创建的相关内联元素:

class MyLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
        if (Control != null && e.NewElement != null)
        {
            Element.PropertyChanged += LabelPropertyChanged;
            SyncFormattedText();                
        }
    }

    private void LabelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == Label.FormattedTextProperty.PropertyName)
        {
            SyncFormattedText();
        }
    }

    private void SyncFormattedText()
    {
        if (Element?.FormattedText != null)
        {
            for (var i = 0; i < Element.FormattedText.Spans.Count; i++)
            {
                if (Element.FormattedText.Spans[i] is ExtendedSpan extendedSpan &&
                    extendedSpan.IsLink &&
                    !(Control.Inlines[i] is Hyperlink))
                {
                    
                    var hyperlink = new Hyperlink();
                    hyperlink.Click += (sender, args) =>
                    {
                        foreach (var gestureRecognizer in extendedSpan.GestureRecognizers)
                        {
                            if (gestureRecognizer is TapGestureRecognizer tap)
                            {
                                tap.Command?.Execute(tap.CommandParameter);
                            }
                        }
                    };
                    hyperlink.Inlines.Add(new Run
                    {
                        Text = extendedSpan.Text
                    });
                    
                    Control.Inlines[i] = hyperlink;
                }
            }
        }
    }

相关问题