Xamarin 形成常见的可重用视图

Xamarin Forms Common Reusable Views

我正在尝试制作一个可重复使用的密码切换可见性视图,以便在许多地方使用它。 但是我找不到合适的方法来做到这一点。 这是我的查看代码

    <Grid>
        <Entry 
        Placeholder="{xct:Translate Password}"
        IsPassword="{Binding Source={x:Reference ShowPasswordActualTrigger}, Path=HidePassword}"
        Text="{Binding Password}"
        Style="{StaticResource EntryStyle}"
        />
        <ImageButton 
                VerticalOptions="Center"
                Margin="0,0,10,10"
                HeightRequest="40"
                WidthRequest="30"
                HorizontalOptions="End"
                BackgroundColor="Transparent"
                Source="{local:ImageResource RealEstateDemo.Images.eye-hidden.png}">
            <ImageButton.Triggers>
                <EventTrigger Event="Clicked">
                    <trigger:ShowPasswordTriggerAction 
                    ShowIcon="{local:ImageResource RealEstateDemo.Images.eye-show.png}"
                    HideIcon="{local:ImageResource RealEstateDemo.Images.eye-hidden.png}"
                    x:Name="ShowPasswordActualTrigger"/>
                </EventTrigger>
            </ImageButton.Triggers>
        </ImageButton>
<Grid/>

我的可重用视图代码正在尝试分离图像按钮代码

<ImageButton   
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="RealEstateDemo.Common.Views.PasswordToggle"
        VerticalOptions="Center"
        Margin="0,0,10,10"
        HeightRequest="40"
        WidthRequest="30"
        HorizontalOptions="End"
        BackgroundColor="Transparent"
        xmlns:img="clr-namespace:RealEstateDemo.Images"
        xmlns:trigger="clr-namespace:RealEstateDemo.Utils.Triggers"
        Source="{img:ImageResource RealEstateDemo.Images.eye-hidden.png}">
    
    <ImageButton.Triggers>
        <EventTrigger Event="Clicked">
            <trigger:ShowPasswordTriggerAction 
                    ShowIcon="{img:ImageResource RealEstateDemo.Images.eye-show.png}"
                    HideIcon="{img:ImageResource RealEstateDemo.Images.eye-hidden.png}"
                    x:Name="ShowPasswordActualTrigger"/>
        </EventTrigger>
    </ImageButton.Triggers>
    
</ImageButton>

然而每次我尝试使用 xmlns

将原始图像按钮代码替换为分离的代码
  xmlns:common="clr-namespace:RealEstateDemo.Common.Views"

<common:PasswordToggle/>

我得到没有兼容的代码运行。

System.Reflection.TargetInvocationException

消息=调用目标抛出异常

我真的为这种幼稚的方法道歉,但我不是 xamarin 表单专家如果有任何其他方法请推荐它以及一般如何使用可重用视图(即网格、按钮等)。 提前致谢。

// 错误完整报告

   android.runtime.JavaProxyThrowable: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Xamarin.Forms.Xaml.XamlParseException: Position 41:13. Can not find the object referenced by ShowPasswordActualTrigger
  at Xamarin.Forms.Xaml.ReferenceExtension.ProvideValue (System.IServiceProvider serviceProvider) [0x000db] in <804f4c0d38d4422eb26003cb4065d911>:0 
  at RealEstateDemo.View.SignInPage.InitializeComponent () [0x00fc3] in <3127c0bdd705413b88b78c5b44f792a4>:0 
  at RealEstateDemo.View.SignInPage..ctor () [0x00008] in <3127c0bdd705413b88b78c5b44f792a4>:0 
  at (wrapper managed-to-native) System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00005] in <1b39a03c32ec46258a7821e202e0269f>:0 
   --- End of inner exception stack trace ---
  at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x0001d] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic, System.Boolean wrapExceptions) [0x00095] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean wrapExceptions, System.Boolean skipCheckThis, System.Boolean fillCache) [0x00009] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Boolean wrapExceptions, System.Threading.StackCrawlMark& stackMark) [0x00027] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic, System.Boolean wrapExceptions) [0x00020] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) [0x00000] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <1b39a03c32ec46258a7821e202e0269f>:0 
  at Xamarin.Forms.ElementTemplate+<>c__DisplayClass4_0.<.ctor>b__0 () [0x00000] in <978ec34c5c9c4c4eb3d73b6da958bcd6>:0 
  at Xamarin.Forms.ElementTemplate.CreateContent () [0x0002c] in <978ec34c5c9c4c4eb3d73b6da958bcd6>:0 
  at Xamarin.Forms.Internals.DataTemplateExtensions.CreateContent (Xamarin.Forms.DataTemplate self, System.Object item, Xamarin.Forms.BindableObject container) [0x00008] in <978ec34c5c9c4c4eb3d73b6da958bcd6>:0 
  at Xamarin.Forms.ShellContent.Xamarin.Forms.IShellContentController.GetOrCreateContent () [0x0002e] in <978ec34c5c9c4c4eb3d73b6da958bcd6>:0 
  at Xamarin.Forms.Platform.Android.ShellSectionRenderer.OnCreateView (Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState) [0x000f8] in <25214d643f8b4b97a15bcdb62359e8e5>:0 
  at AndroidX.Fragment.App.Fragment.n_OnCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_inflater, System.IntPtr native_container, System.IntPtr native_savedInstanceState) [0x00020] in <f41f102784094fa586a15d45dcf87d88>:0 
  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.64(intptr,intptr,intptr,intptr,intptr)
--- End of stack trace from previous location where exception was thrown ---

  at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <bd6bd528a8784b7caf03e9f25c9f0d7b>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00063] in <bd6bd528a8784b7caf03e9f25c9f0d7b>:0 
  at Android.App.Activity.OnStart () [0x0000a] in <db0280fb1b254cf889f3a750ac3ea0bb>:0 
  at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnStart () [0x0001e] in <25214d643f8b4b97a15bcdb62359e8e5>:0 
  at Android.App.Activity.n_OnStart (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <db0280fb1b254cf889f3a750ac3ea0bb>:0 
  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.14(intptr,intptr)
    at crc643f46942d9dd1fff9.FormsAppCompatActivity.n_onStart(Native Method)
    at crc643f46942d9dd1fff9.FormsAppCompatActivity.onStart(FormsAppCompatActivity.java:128)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392)
    at android.app.Activity.performStart(Activity.java:7252)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:1

父视图不知道自定义控件中的 ShowPasswordActualTrigger 引用是什么。

您可能希望您的自定义控件公开一个可绑定的 属性 让父视图知道您是否要显示密码。