如何使用Xamarin.Forms中的外部浏览器创建可点击标签以打开外部URL?

时间:2016-05-12 03:36:51

标签: xamarin xamarin.forms

Xamarin中没有类似LinkBut​​ton的东西吗?

我想创建一个带有url链接外观的标签,一旦点击,就会打开外部浏览器。

我还需要知道如何在便携式项目中打开设备的外部浏览器(打开指定的URL)。

由于

3 个答案:

答案 0 :(得分:9)

在默认移动浏览器中以Xamarin.Forms方式打开网址字符串:

Device.OpenUri(new Uri("http://example.com"))

虽然表格' Label没有点击事件,您可以添加TapGestureRecognizer,因此当标签点击时,它会执行Device.OpenUri

实施例

var myURLLabel = new Label
{
    Text = "https://xamarin.com"
};

myURLLabel.GestureRecognizers.Add(new TapGestureRecognizer
{
    Command = new Command(() => {
        Device.OpenUri(new Uri(myURLLabel.Text));
    })
});

Xamarin窗体-实验室' ExtendedLabel允许您将标签的文字设置为带下划线的....

参考:https://github.com/XLabs/Xamarin-Forms-Labs/wiki/ExtendedLabel

答案 1 :(得分:2)

创建一个可以显示带下划线的标签(或使用Xamarin Forms Labs ExtendedLabel):

using Xamarin.Forms;

public class ExtendedLabel : Label
{
    public static readonly BindableProperty IsUnderlinedProperty = BindableProperty.Create<ExtendedLabel, bool>(p => p.IsUnderlined, false);

    public bool IsUnderlined
    {
        get { return (bool)GetValue(IsUnderlinedProperty); }
        set { SetValue(IsUnderlinedProperty, value); }
    }

    // ...other custom properties

}

处理自定义渲染器中的IsUnderlined属性:

public class ExtendedLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        // ...
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == ExtendedLabel.IsUnderlinedProperty.PropertyName)
        {
            RefreshControl(Control);
        }
    }

    private void RefreshControl(UILabel control)
    {
        if (control == null) return;

        // Apply based on IsUnderlined property
        if (!string.IsNullOrEmpty(control.Text)) control.AttributedText = new NSMutableAttributedString(control.Text, underlineStyle: view.IsUnderlined ? NSUnderlineStyle.Single : NSUnderlineStyle.None);            

        // ...apply based on other custom properties
    }
}

将您的标签控件添加到YourPage.xaml并添加手势识别器以处理点击:

<controls:ExtendedLabel
    Text="View in browser"
    TextColor="Blue"
    IsUnderlined="True">
    <controls:ExtendedLabel.GestureRecognizers>
        <!--TODO:<TapGestureRecognizer Command="TapCommand" /> Couldn't do this for some reason so use Tapped handler-->
        <TapGestureRecognizer
            Tapped="OnOpenInBrowserTapGestureRecognizerTapped"
            NumberOfTapsRequired="1" />
    </controls:ExtendedLabel.GestureRecognizers>
</controls:ExtendedLabel>

处理YourPage.xaml.cs背后的代码:

private void OnOpenInBrowserTapGestureRecognizerTapped(object sender, EventArgs args)
{
    var labelViewSender = (ExtendedLabel)sender;

    labelViewSender.Opacity = 0.6;
    labelViewSender.FadeTo(1);

    var viewModel = BindingContext as YourPageViewModel;
    if (viewModel == null) return;

    if (viewModel.NavigateToUrlCommand.CanExecute(null)) viewModel.NavigateToUrlCommand.Execute(null);
}

视图模型:

public class YourPageViewModel : ViewModelBase
{
    public const string NavigateToUrlMessage = "NavigateToUrl";

    private string _url;
    public string Url
    {
        get { return _url; }
        set { SetProperty(ref _url, value); }
    }

    //...

    private Command _navigateToUrlCommand;
    public ICommand NavigateToUrlCommand
    {
        get { return _navigateToUrlCommand ?? (_navigateToUrlCommand = new Command(param => NavigateToUrl(), CanNavigateToUrl)); }
    }

    public bool CanNavigateToUrl(object parameter) => true;

    private void NavigateToUrl()
    {
        MessagingCenter.Send(this, NavigateToUrlMessage, Url);
    }

    //...
}

订阅并处理YourPage.xaml.cs代码中的NavigateToUrlMessage消息:

    protected override void OnAppearing()
    {
        MessagingCenter.Subscribe<YourPageViewModel, string>(this, YourPageViewModel.NavigateToUrlMessage, (sender, args) =>
        {
            var context = (BindingContext as YourPageViewModel);
            if (context == null) return;

            if (string.IsNullOrEmpty(args)) return;

            Device.BeginInvokeOnMainThread(() =>
            {
                Device.OpenUri(new Uri(args));
            });
        });

        //...

        base.OnAppearing();
    }

    protected override void OnDisappearing()
    {
        MessagingCenter.Unsubscribe<YourPageViewModel, string>(this, YourPageViewModel.NavigateToUrlMessage);

        //...

        base.OnDisappearing();
    }

答案 2 :(得分:0)

对于Xamarin.Forms 3.2及更高版本

<Label>
    <Label.FormattedText>
        <FormattedString>
            <Span Text="{Binding Url, Mode=OneWay}" TextColor="Blue">
                <Span.GestureRecognizers>
                        <TapGestureRecognizer 
                            Command="{Binding TapCommand, Mode=OneWay}"
                            CommandParameter="https://www.xamarin.com"/>
                </Span.GestureRecognizers>
            </Span>
        </FormattedString>
    </Label.FormattedText>
</Label>

您可以使用带有或不带有参数的命令,或者仅使用敲击事件。

示例:

<Label>
            <Label.FormattedText>
                <FormattedString>
                    <Span Text="Xamarin" TextColor="Blue">
                        <Span.GestureRecognizers>
                            <TapGestureRecognizer 
                                Command="{Binding TapCommand, Mode=OneWay}"
                                CommandParameter="https://www.xamarin.com"/>
                        </Span.GestureRecognizers>
                    </Span>
                </FormattedString>
            </Label.FormattedText>
        </Label>

在ViewModel中:

private ICommand _tapCommand;
public ICommand TapCommand =>
_tapCommand ?? (_tapCommand = new Command<string>(OpenUrl));

void OpenUrl(string url)
{
   Device.OpenUri(new Uri(url));
}