C# 使用Xamarin.Forms自定义呈现程序时转发事件/命令

C# 使用Xamarin.Forms自定义呈现程序时转发事件/命令,c#,mvvm,xamarin,xamarin.forms,C#,Mvvm,Xamarin,Xamarin.forms,在我的Xamarin.Forms应用程序中,我希望自定义按钮的外观和感觉,使其达到比允许的更高的程度,因此我使用自定义渲染器将Windows Phone 8.1上Xamarin.Forms中的默认控件替换为我自己的按钮控件 我的控件只是扩展了按钮,稍后将添加额外的属性 public class ButtonControl : Button {} Windows Phone 8.1上的自定义渲染器: public class ButtonControlRenderer : ViewRendere

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

我的控件只是扩展了按钮,稍后将添加额外的属性

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控件上触发一个事件,比如Clicked,我该怎么做呢?我是否会重写ButtonControl中的Clicked事件,而不是从Button类继承并添加一个方法从那里触发事件?

Button.Tapped+=handler
就是这样做的。但是您不必执行命令,只需对元素调用
SendClicked()
。这将执行命令并触发
单击的事件。标准渲染器也在这样做

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

public类按钮控件渲染器:视图渲染器
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
//您的创建代码。。。
按钮。点击+=打开按钮点击;
}
私有void OnButtonTapped(…)
{
((IButtonController)元素)?.SendClicked();
}
受保护的覆盖无效处置(布尔处置)
{
if(控件!=null)
控制。点击-=打开按钮;
基地。处置(处置);
}
}

button.Tapped+=handler
就是这样做的。但是您不必执行命令,只需对元素调用
SendClicked()
。这将执行命令并触发
单击的事件。标准渲染器也在这样做

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

public类按钮控件渲染器:视图渲染器
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
//您的创建代码。。。
按钮。点击+=打开按钮点击;
}
私有void OnButtonTapped(…)
{
((IButtonController)元素)?.SendClicked();
}
受保护的覆盖无效处置(布尔处置)
{
if(控件!=null)
控制。点击-=打开按钮;
基地。处置(处置);
}
}

Perfect,非常感谢,寻找了一种方法,但没有向IButtonController强制转换,因此从未找到它。关于处置的好提示!完美,非常感谢,寻找了一种方法,但没有向IButtonController施压,因此从未找到它。关于处置的好提示!
<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>
button.Tapped += delegate
      {
        Element.Command.Execute(null);
      };