Xamarin Forms UWP 工具提示

3
我想在Xamarin中使用本地视图和Windows.UI.Xaml Nuget包来为UWP添加工具提示。我已经在xaml页面中添加了以下引用以获取Windows本地视图:
<ContentPage 

             xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"   

</ContentPage>

我能成功访问本地Windows控件,例如TextBlock:

<    win: TextBlock Text="S"/>

然而,当我试图将工具提示添加到控件时:
<win:TextBlock Text="S" ToolTipService.ToolTip="Service agreement"/>

编译时出现以下异常:

"Xamarin.Forms.Xaml.XamlParseException: '位置 56:45。在命名空间 xmlns http://xamarin.com/schemas/2014/forms 中未找到类型 ToolTipService'"

这是系统是否在标准的Windows.UI.Xaml.Controls命名空间和来自Nuget包的扩展命名空间之间感到困惑?


我搜索了一些信息,但是我找不到任何方法来为表单中的本地视图添加工具提示。如果您想要实现这一点,我建议您可以为您想要显示工具提示的任何控件自定义渲染器。这是一个相同的线程,您可以参考一下:https://stackoverflow.com/questions/41978916/xamarin-forms-tooltip-in-windows-app - Cherry Bu - MSFT
@CherryBu-MSFT:谢谢。您是否建议我按照此处所述自定义条目:https://learn.microsoft.com/en-gb/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry?还是在UWP中有一个特定于TextBox的渲染器可以使用? - ccdmfc
1个回答

5

ToolTipService 是一个附加属性,Forms客户端中不会找到 ToolTipService 组件,更好的方法是使用 Effect 来创建你自己的提示服务,并在UWP平台上呈现它。您可以参考以下步骤:

  • 创建 PlatformEffect 类的子类。

  • 重写 OnAttached 方法并编写逻辑以自定义控件。

  • 重写 OnDetached 方法并编写逻辑以清除控件自定义(如果需要)。

  • 向效果类添加ResolutionGroupName属性。此属性设置了一组公司范围的命名空间,可防止与其他具有相同名称的效果发生冲突。请注意,此属性每个项目只能应用一次。

  • 向效果类添加 ExportEffect 属性。此属性使用独特的 ID 注册效果,Xamarin.Forms 与组名一起使用此 ID,在将其应用于控件之前定位效果。该属性接受两个参数 - 效果的类型名称和将用于在将其应用于控件之前定位效果的唯一字符串。

UWP 代码部分

[assembly: ResolutionGroupName("Microsoft")]
[assembly: ExportEffect(typeof(UWPToolTipEffect), nameof(TooltipEffect))]

namespace NativeSwitch.UWP
{
    public class UWPToolTipEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            var control = Control ?? Container;

            if (control is DependencyObject)
            {
                ToolTip toolTip = new ToolTip();
                toolTip.Content = TooltipEffect.GetText(Element);
                switch (TooltipEffect.GetPosition(Element))
                {
                    case TooltipPosition.Bottom:
                        toolTip.Placement = Windows.UI.Xaml.Controls.Primitives.PlacementMode.Bottom;
                        break;
                    case TooltipPosition.Top:
                        toolTip.Placement = Windows.UI.Xaml.Controls.Primitives.PlacementMode.Top;
                        break;
                    case TooltipPosition.Left:
                        toolTip.Placement = Windows.UI.Xaml.Controls.Primitives.PlacementMode.Left;
                        break;
                    case TooltipPosition.Right:
                        toolTip.Placement = Windows.UI.Xaml.Controls.Primitives.PlacementMode.Right;
                        break;
                    default:
                        return;
                }
                ToolTipService.SetToolTip(control, toolTip);
            }

        }

        protected override void OnDetached()
        {

        }
    }
}

表单代码部分

public static class TooltipEffect
{

    public static readonly BindableProperty TextProperty =
      BindableProperty.CreateAttached("Text", typeof(string), typeof(TooltipEffect), string.Empty, propertyChanged: OnTextChanged);

    public static readonly BindableProperty PositionProperty =
      BindableProperty.CreateAttached("Position", typeof(TooltipPosition), typeof(TooltipEffect), TooltipPosition.Bottom);


    public static string GetText(BindableObject view)
    {
        return (string)view.GetValue(TextProperty);
    }

    public static void SetText(BindableObject view, string value)
    {
        view.SetValue(TextProperty, value);
    }

    public static TooltipPosition GetPosition(BindableObject view)
    {
        return (TooltipPosition)view.GetValue(PositionProperty);
    }

    public static void SetPosition(BindableObject view, TooltipPosition value)
    {
        view.SetValue(PositionProperty, value);
    }

    static void OnTextChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var view = bindable as View;
        if (view == null)
        {
            return;
        }

        string text = (string)newValue;
        if (!string.IsNullOrEmpty(text))
        {
            view.Effects.Add(new ControlTooltipEffect());
        }
        else
        {
            var toRemove = view.Effects.FirstOrDefault(e => e is ControlTooltipEffect);
            if (toRemove != null)
            {
                view.Effects.Remove(toRemove);
            }
        }
    }

}

public enum TooltipPosition
{
    Bottom,

    Right,

    Left,

    Top
}

class ControlTooltipEffect : RoutingEffect
{
    public ControlTooltipEffect() : base($"Microsoft.{nameof(TooltipEffect)}")
    {

    }
}

使用方法

// forms project namesapce
xmlns:effects="clr-namespace:ToolTipTestApp"
......

<win:TextBlock
    effects:TooltipEffect.Position="Right"
    effects:TooltipEffect.Text="Hello"
    Text="Hello Wrold"
    />

如何在上面的示例中支持多行工具提示? - Karthik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接