繁体   English   中英

使用Xamarin.Forms自定义渲染器时转发事件/命令

[英]Forwarding events/commands when using Xamarin.Forms Custom Renderer

在我的Xamarin.Forms应用程序中,我希望自定义按钮的外观和感觉的程度高于允许的程度,因此我使用自定义渲染器将Windows Phone 8.1的Xamarin.Forms中的默认控件替换为自己的按钮控件。

我的控件仅扩展Button,以后将添加其他属性。

public class ButtonControl : Button {}

我在Windows Phone 8.1上的自定义渲染器:

public class ButtonControlRenderer : ViewRenderer<ButtonControl, Button>
  {
    protected override void OnElementChanged(ElementChangedEventArgs<ButtonControl> e)
    {
      base.OnElementChanged(e);

      if (e.OldElement != null || Element == null)
        return;

      var button = new Button
      {
        Style = Application.Current.Resources["ButtonWithTilt"] as Style,
        Content = Element.Text,
        IsEnabled = Element.IsEnabled
      };

      Element.BackgroundColor = Color.Transparent;

      SetNativeControl(button);
    }
  }

而且,我如何使用Xamarin.Forms XAML文件中的控件:

<StackLayout VerticalOptions="Center"
                         HorizontalOptions="Fill"
                         Margin="24,12,24,0">
              <controls:ButtonControl Text="{res:Translate LoginPageButtonText}"
                      TextColor="{x:Static const:Colours.OverlayColor}"
                      BackgroundColor="{x:Static const:Colours.PrimaryColor}"
                      BorderWidth="0"
                      Margin="0,24,0,0"
                      HeightRequest="50"
                      IsEnabled="{Binding LoginValid}"
                      Command="{Binding LoginCommand}"
                      StyleId="{x:Static const:StyleIds.LoginPageButton}"/>
            </StackLayout>

当我替换按钮时,我的命令无法立即使用,我必须在OnElementChanged中添加以下内容,以便在单击新按钮时执行命令:

button.Tapped += delegate
      {
        Element.Command.Execute(null);
      };

这似乎不是最干净的解决方案,是否有更好的方法来进行连接?

另外,如果有一个事件想在基本Xamarin.Forms控件上触发,例如Clicked,我将如何处理? 我是否会重写ButtonControl中的Clicked事件,而不是从Button类继承并添加一个从那里触发事件的方法?

button.Tapped += handler 但是不必执行命令,只需在Element上调用SendClicked() 这将执行命令触发Clicked事件。 标准渲染器也是如此。

您应该将匿名委托转换为类中的方法,以便能够在清除时注销事件,以防止内存泄漏。

public class ButtonControlRenderer : ViewRenderer<ButtonControl, Button>
{
    protected override void OnElementChanged(ElementChangedEventArgs<ButtonControl> e)
    {
        //your creation code ...            
        button.Tapped += OnButtonTapped;
    }

    private void OnButtonTapped(...)
    {
        ((IButtonController)Element)?.SendClicked();
    }

    protected override void Dispose(bool disposing)
    {
        if (Control != null)
            Control.Tapped -= OnButtonTapped;

        base.Dispose(disposing);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM