C# 如何从EventToCommandBehavior分离?
在使用从这里获得的EventToCommandBehavior类时,我似乎遇到了重复事件: 我遵循的是MVVM模式,因此在我的XAML中有以下内容:C# 如何从EventToCommandBehavior分离?,c#,xamarin,C#,Xamarin,在使用从这里获得的EventToCommandBehavior类时,我似乎遇到了重复事件: 我遵循的是MVVM模式,因此在我的XAML中有以下内容: <Switch IsToggled="{Binding FilterOptions.IsActive}" HorizontalOptions="Center"> <Switch.Behaviors> <behaviour:EventToCommandBehaviour Event
<Switch IsToggled="{Binding FilterOptions.IsActive}"
HorizontalOptions="Center">
<Switch.Behaviors>
<behaviour:EventToCommandBehaviour EventName="Toggled" Command="{Binding OnActiveCommand}" CommandParameter="{Binding FilterOptions.IsActive}" />
</Switch.Behaviors>
</Switch>
public ICommand OnActiveCommand => new Command<Boolean>(OnActive);
public ICommand OnDiscontinuedCommand => new Command<Boolean>(OnDiscontinued);
private void OnDiscontinued(Boolean value) {
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
if (!value) {
FilterOptions.IsActive = false;
}
}
private void OnActive(Boolean value) {
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
if (!value) {
FilterOptions.IsDiscontinued = false;
}
}
在我的ViewModel中,我有:
<Switch IsToggled="{Binding FilterOptions.IsActive}"
HorizontalOptions="Center">
<Switch.Behaviors>
<behaviour:EventToCommandBehaviour EventName="Toggled" Command="{Binding OnActiveCommand}" CommandParameter="{Binding FilterOptions.IsActive}" />
</Switch.Behaviors>
</Switch>
public ICommand OnActiveCommand => new Command<Boolean>(OnActive);
public ICommand OnDiscontinuedCommand => new Command<Boolean>(OnDiscontinued);
private void OnDiscontinued(Boolean value) {
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
if (!value) {
FilterOptions.IsActive = false;
}
}
private void OnActive(Boolean value) {
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
if (!value) {
FilterOptions.IsDiscontinued = false;
}
}
public-ICommand-OnActiveCommand=>new命令(OnActive);
public ICommand OnDiscontinued=>new命令(OnDiscontinued);
私有void OnDiscontinued(布尔值){
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
如果(!值){
FilterOptions.IsActive=false;
}
}
私有void OnActive(布尔值){
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
如果(!值){
FilterOptions.IsDiscontinued=false;
}
}
它完美地连接在一起,当我与开关交互时,命令按预期调用。但是,我注意到,如果我关闭当前页面并返回到它,当我与任何开关交互时,命令会重复吗
我在OnDetachingFrom()上(在BahviourBase.cs中)和DeregisterEvent()上(在eventToCommandBehavior.cs中)放置了一个断点,假设在关闭页面时可以调用它们?二者均如下所示: BahviourBase.cs
public class BehaviourBase<T> : Behavior<T> where T : BindableObject {
public T AssociatedObject { get; private set; }
protected override void OnAttachedTo(T bindable) {
base.OnAttachedTo(bindable);
AssociatedObject = bindable;
if (bindable.BindingContext != null) {
BindingContext = bindable.BindingContext;
}
bindable.BindingContextChanged += OnBindingContextChanged;
}
protected override void OnDetachingFrom(T bindable) {
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= OnBindingContextChanged;
AssociatedObject = null;
}
void OnBindingContextChanged(object sender, EventArgs e) {
OnBindingContextChanged();
}
protected override void OnBindingContextChanged() {
base.OnBindingContextChanged();
BindingContext = AssociatedObject.BindingContext;
}
}
public class EventToCommandBehaviour : BehaviourBase<View> {
Delegate eventHandler;
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehaviour), null, propertyChanged: OnEventNameChanged);
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehaviour), null);
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehaviour), null);
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehaviour), null);
public string EventName {
get { return (string)GetValue(EventNameProperty); }
set { SetValue(EventNameProperty, value); }
}
public ICommand Command {
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter {
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public IValueConverter Converter {
get { return (IValueConverter)GetValue(InputConverterProperty); }
set { SetValue(InputConverterProperty, value); }
}
protected override void OnAttachedTo(View bindable) {
base.OnAttachedTo(bindable);
RegisterEvent(EventName);
}
protected override void OnDetachingFrom(View bindable) {
DeregisterEvent(EventName);
base.OnDetachingFrom(bindable);
}
void RegisterEvent(string name) {
if (string.IsNullOrWhiteSpace(name)) {
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null) {
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
}
MethodInfo methodInfo = typeof(EventToCommandBehaviour).GetTypeInfo().GetDeclaredMethod("OnEvent");
eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
eventInfo.AddEventHandler(AssociatedObject, eventHandler);
}
void DeregisterEvent(string name) {
if (string.IsNullOrWhiteSpace(name)) {
return;
}
if (eventHandler == null) {
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null) {
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
}
eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
eventHandler = null;
}
void OnEvent(object sender, object eventArgs) {
if (Command == null) {
return;
}
object resolvedParameter;
if (CommandParameter != null) {
resolvedParameter = CommandParameter;
} else if (Converter != null) {
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
} else {
resolvedParameter = eventArgs;
}
if (Command.CanExecute(resolvedParameter)) {
Command.Execute(resolvedParameter);
}
}
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue) {
var behavior = (EventToCommandBehaviour)bindable;
if (behavior.AssociatedObject == null) {
return;
}
string oldEventName = (string)oldValue;
string newEventName = (string)newValue;
behavior.DeregisterEvent(oldEventName);
behavior.RegisterEvent(newEventName);
}
}
公共类行为库:行为,其中T:BindableObject{
公共T关联对象{get;私有集;}
受保护的覆盖无效数据到(T可绑定){
碱。可粘合的DTO(可粘合);
AssociatedObject=可绑定;
if(bindable.BindingContext!=null){
BindingContext=bindable.BindingContext;
}
bindable.BindingContextChanged+=OnBindingContextChanged;
}
受保护的覆盖无效OnDetachingFrom(T可绑定){
基础。从(可装订)开始连接;
bindable.BindingContextChanged-=OnBindingContextChanged;
AssociatedObject=null;
}
void OnBindingContextChanged(对象发送方,事件参数e){
OnBindingContextChanged();
}
受保护的覆盖无效OnBindingContextChanged(){
base.OnBindingContextChanged();
BindingContext=AssociatedObject.BindingContext;
}
}
eventtocommandbehavior.cs
public class BehaviourBase<T> : Behavior<T> where T : BindableObject {
public T AssociatedObject { get; private set; }
protected override void OnAttachedTo(T bindable) {
base.OnAttachedTo(bindable);
AssociatedObject = bindable;
if (bindable.BindingContext != null) {
BindingContext = bindable.BindingContext;
}
bindable.BindingContextChanged += OnBindingContextChanged;
}
protected override void OnDetachingFrom(T bindable) {
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= OnBindingContextChanged;
AssociatedObject = null;
}
void OnBindingContextChanged(object sender, EventArgs e) {
OnBindingContextChanged();
}
protected override void OnBindingContextChanged() {
base.OnBindingContextChanged();
BindingContext = AssociatedObject.BindingContext;
}
}
public class EventToCommandBehaviour : BehaviourBase<View> {
Delegate eventHandler;
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehaviour), null, propertyChanged: OnEventNameChanged);
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehaviour), null);
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehaviour), null);
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehaviour), null);
public string EventName {
get { return (string)GetValue(EventNameProperty); }
set { SetValue(EventNameProperty, value); }
}
public ICommand Command {
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter {
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public IValueConverter Converter {
get { return (IValueConverter)GetValue(InputConverterProperty); }
set { SetValue(InputConverterProperty, value); }
}
protected override void OnAttachedTo(View bindable) {
base.OnAttachedTo(bindable);
RegisterEvent(EventName);
}
protected override void OnDetachingFrom(View bindable) {
DeregisterEvent(EventName);
base.OnDetachingFrom(bindable);
}
void RegisterEvent(string name) {
if (string.IsNullOrWhiteSpace(name)) {
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null) {
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
}
MethodInfo methodInfo = typeof(EventToCommandBehaviour).GetTypeInfo().GetDeclaredMethod("OnEvent");
eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
eventInfo.AddEventHandler(AssociatedObject, eventHandler);
}
void DeregisterEvent(string name) {
if (string.IsNullOrWhiteSpace(name)) {
return;
}
if (eventHandler == null) {
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null) {
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
}
eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
eventHandler = null;
}
void OnEvent(object sender, object eventArgs) {
if (Command == null) {
return;
}
object resolvedParameter;
if (CommandParameter != null) {
resolvedParameter = CommandParameter;
} else if (Converter != null) {
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
} else {
resolvedParameter = eventArgs;
}
if (Command.CanExecute(resolvedParameter)) {
Command.Execute(resolvedParameter);
}
}
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue) {
var behavior = (EventToCommandBehaviour)bindable;
if (behavior.AssociatedObject == null) {
return;
}
string oldEventName = (string)oldValue;
string newEventName = (string)newValue;
behavior.DeregisterEvent(oldEventName);
behavior.RegisterEvent(newEventName);
}
}
公共类事件到CommandBehavior:行为库{
委托事件处理程序;
public static readonly BindableProperty EventNameProperty=BindableProperty.Create(“EventName”、typeof(string)、typeof(eventToCommandBehavior)、null、propertyChanged:OnEventNameChanged);
public static readonly BindableProperty CommandProperty=BindableProperty.Create(“命令”、typeof(ICommand)、typeof(eventtocommandbehavior)、null);
public static readonly BindableProperty CommandParameterProperty=BindableProperty.Create(“CommandParameter”、typeof(object)、typeof(eventToCommandBehavior)、null);
public static readonly BindableProperty InputConverterProperty=BindableProperty.Create(“转换器”、typeof(IValueConverter)、typeof(eventtocommandbehavior)、null);
公共字符串事件名{
获取{return(string)GetValue(EventNameProperty);}
set{SetValue(EventNameProperty,value);}
}
公共ICommand命令{
获取{return(ICommand)GetValue(CommandProperty);}
set{SetValue(CommandProperty,value);}
}
公共对象命令参数{
获取{return GetValue(CommandParameterProperty);}
set{SetValue(CommandParameterProperty,value);}
}
公用变频器{
获取{return(IValueConverter)GetValue(InputConverterProperty);}
set{SetValue(InputConverterProperty,value);}
}
受保护的替代数据(视图可绑定){
碱。可粘合的DTO(可粘合);
RegisterEvent(事件名称);
}
受保护的覆盖无效OnDetachingFrom(视图可绑定){
注销事件(事件名称);
基础。从(可装订)开始连接;
}
无效RegisterEvent(字符串名称){
if(string.IsNullOrWhiteSpace(name)){
返回;
}
EventInfo EventInfo=AssociatedObject.GetType().GetRuntimeEvent(名称);
if(eventInfo==null){
抛出新的ArgumentException(string.Format(“EventToCommandBehavior:无法注册“{0}”事件。”,EventName));
}
MethodInfo MethodInfo=typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod(“OneEvent”);
eventHandler=methodInfo.CreateDelegate(eventInfo.EventHandlerType,this);
AddEventHandler(关联对象,eventHandler);
}
作废注销事件(字符串名称){
if(string.IsNullOrWhiteSpace(name)){
返回;
}
if(eventHandler==null){
返回;
}
EventInfo EventInfo=AssociatedObject.GetType().GetRuntimeEvent(名称);
if(eventInfo==null){
抛出新的ArgumentException(string.Format(“EventToCommandBehavior:无法取消注册“{0}”事件。”,EventName));
}
RemoveEventHandler(关联对象,eventHandler);
eventHandler=null;
}
void OnEvent(对象发送方、对象事件参数){
如果(命令==null){
返回;
}
对象解析参数;
if(CommandParameter!=null){
resolvedParameter=命令参数;
}else if(转换器!=null){
resolvedParameter=Converter.Convert(eventArgs,typeof(object),null,null);
}否则{
resolvedParameter=eventArgs;
}
if(Command.CanExecute(resolvedParameter)){
Command.Execute(resolvedParameter);
}
}
静态void OnEventNameChanged(BindableObject bindable、object oldValue、object newValue){
变量行为=(EventToCommandBehavior)可绑定;
if(behavior.AssociatedObject==null){
返回;
}
字符串oldEventName=(字符串)oldValue;
字符串newEventName=(字符串)newValue;