Xamarin Forms 自定义控制命令未被解雇
Xamarin Forms Custom Control Command not getting fired
我正在创建一个特定于平台的自定义按钮,其文本和图像在 Android 和 iOS 中具有自定义渲染器。我的问题是,我的按钮上的 Click Command 没有被触发。
我创建了自定义 android 渲染器,强制使用自定义 android 布局。
Xamarin.Form 按钮 Class:
public static readonly BindableProperty CommandProperty =
BindableProperty.Create("Command", typeof(ICommand), typeof(ImageButton), null,
BindingMode.TwoWay, propertyChanged: OnCommandChanged);
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public EventHandler Clicked;
private static void OnCommandChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (ImageButton)bindable;
// this gesture recognizer will inovke the command event whereever it is used
control.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = (Command)newValue,
CommandParameter = control.CommandParams
});
}
public ImageButton()
{
this.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = new Command(() =>
{
Clicked?.Invoke(this, EventArgs.Empty);
if (Command != null)
{
if (Command.CanExecute(CommandParams))
Command.Execute(CommandParams);
}
})
});
}
Android 渲染器:
[assembly: ExportRenderer(typeof(ImageButton), typeof(ImageButtonRenderer))]
namespace Droid.Extensions.Renderers
{
public class ImageButtonRenderer : ViewRenderer<ImageButton, Android.Views.View>
{
private readonly Context context;
private TextView buttonText;
private ImageView buttonIcon;
public ImageButtonRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Controls.ImageButton> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var inflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
var rootLayout = inflater.Inflate(Resource.Layout.ImageButton, null, false);
buttonText = (TextView) rootLayout.FindViewById(Resource.Id.image_button_text);
buttonText.Text = Element.Text;
buttonIcon = (ImageView)rootLayout.FindViewById(Resource.Id.image_button_icon);
SetNativeControl(rootLayout);
rootLayout.Click += (s, a) => Element.Command?.Execute(a);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
}
}
消耗控制:
<control:ImageButton
Source="ai_tab_menu"
Margin="10"
Command="{Binding MyCommand}"
Text="This is a test!">
查看模型:
public class TabHomeMenuViewModel : INotifyPropertyChanged
{
string message = string.Empty;
public string Message
{
get { return message; }
set
{
message = value;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs("Message"));
}
}
public Command MyCommand { get; private set; }
public TabHomeMenuViewModel()
{
// configure the TapCommand with a method
Message = "Waiting";
MyCommand = new Command(UpdateVersion);
}
private void UpdateVersion()
{
Message += "Clicked ";
}
public event PropertyChangedEventHandler PropertyChanged;
}
我也有同样的问题。我试图通过 BehaviorsPack 绑定一个命令。它与原始元素完美搭配。自定义控件不起作用。我在 xamarin formum 中发布了一个主题,但没有得到答案:https://forums.xamarin.com/discussion/182224/entry-works-with-eventtocommandbehavior-custom-renderner-does-not
我找到了我的代码的问题。我正在将点击事件分配给不可点击的根布局。所以我将点击分配给内部布局。
SetNativeControl(rootLayout);
rootLayout.FindViewById(Resource.Id.image_button).Click += (s, a) =>
{
Element.RaiseCommand();
};
此外,我们必须将事件从 Native Control 冒泡到 Forms。
public void RaiseCommand()
{
Clicked?.Invoke(this, EventArgs.Empty);
if (Command != null && Command.CanExecute(CommandParams))
Command.Execute(CommandParams);
}
我正在创建一个特定于平台的自定义按钮,其文本和图像在 Android 和 iOS 中具有自定义渲染器。我的问题是,我的按钮上的 Click Command 没有被触发。
我创建了自定义 android 渲染器,强制使用自定义 android 布局。
Xamarin.Form 按钮 Class:
public static readonly BindableProperty CommandProperty =
BindableProperty.Create("Command", typeof(ICommand), typeof(ImageButton), null,
BindingMode.TwoWay, propertyChanged: OnCommandChanged);
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public EventHandler Clicked;
private static void OnCommandChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (ImageButton)bindable;
// this gesture recognizer will inovke the command event whereever it is used
control.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = (Command)newValue,
CommandParameter = control.CommandParams
});
}
public ImageButton()
{
this.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = new Command(() =>
{
Clicked?.Invoke(this, EventArgs.Empty);
if (Command != null)
{
if (Command.CanExecute(CommandParams))
Command.Execute(CommandParams);
}
})
});
}
Android 渲染器:
[assembly: ExportRenderer(typeof(ImageButton), typeof(ImageButtonRenderer))]
namespace Droid.Extensions.Renderers
{
public class ImageButtonRenderer : ViewRenderer<ImageButton, Android.Views.View>
{
private readonly Context context;
private TextView buttonText;
private ImageView buttonIcon;
public ImageButtonRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Controls.ImageButton> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var inflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
var rootLayout = inflater.Inflate(Resource.Layout.ImageButton, null, false);
buttonText = (TextView) rootLayout.FindViewById(Resource.Id.image_button_text);
buttonText.Text = Element.Text;
buttonIcon = (ImageView)rootLayout.FindViewById(Resource.Id.image_button_icon);
SetNativeControl(rootLayout);
rootLayout.Click += (s, a) => Element.Command?.Execute(a);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
}
}
消耗控制:
<control:ImageButton
Source="ai_tab_menu"
Margin="10"
Command="{Binding MyCommand}"
Text="This is a test!">
查看模型:
public class TabHomeMenuViewModel : INotifyPropertyChanged
{
string message = string.Empty;
public string Message
{
get { return message; }
set
{
message = value;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs("Message"));
}
}
public Command MyCommand { get; private set; }
public TabHomeMenuViewModel()
{
// configure the TapCommand with a method
Message = "Waiting";
MyCommand = new Command(UpdateVersion);
}
private void UpdateVersion()
{
Message += "Clicked ";
}
public event PropertyChangedEventHandler PropertyChanged;
}
我也有同样的问题。我试图通过 BehaviorsPack 绑定一个命令。它与原始元素完美搭配。自定义控件不起作用。我在 xamarin formum 中发布了一个主题,但没有得到答案:https://forums.xamarin.com/discussion/182224/entry-works-with-eventtocommandbehavior-custom-renderner-does-not
我找到了我的代码的问题。我正在将点击事件分配给不可点击的根布局。所以我将点击分配给内部布局。
SetNativeControl(rootLayout);
rootLayout.FindViewById(Resource.Id.image_button).Click += (s, a) =>
{
Element.RaiseCommand();
};
此外,我们必须将事件从 Native Control 冒泡到 Forms。
public void RaiseCommand()
{
Clicked?.Invoke(this, EventArgs.Empty);
if (Command != null && Command.CanExecute(CommandParams))
Command.Execute(CommandParams);
}