Maui event to command behavior how to get sender and args inside command?

1.7k Views Asked by At

Style code:

<Style x:Key="SpacesQuestionEditor" TargetType="Editor">
        <Setter Property="behaviors:TestEditorStyleBehavior.AttachBehavior">
            <Setter.Value>
                    <toolkit:EventToCommandBehavior EventName="TextChanged"                                                    
                                                    Command="{Binding Source={x:Reference TestEditorPage}, Path=BindingContext.EditorTextChangedCommand}"
                                                    CommandParameter="{Binding .}"/>
    


                </Setter.Value>
        </Setter>
</Style>

Editor code:

<Editor x:Name="spacesTextEditor" Placeholder="Enter text" Style="{StaticResource SpacesQuestionEditor}" Text="{Binding SpacesEditorText}" AutoSize="TextChanges"/>

Command from view model code:

[RelayCommand]
public void EditorTextChanged(TestQuestion testQuestion)
{            
   ChangeHtml(testQuestion);         
}     

Attach behavior code:

 public class TestEditorStyleBehavior : Behavior<Editor>
    {
        public static readonly BindableProperty AttachBehaviorProperty = BindableProperty.CreateAttached(
            propertyName: "AttachBehavior", 
            returnType:typeof(object), 
            declaringType: typeof(TestEditorStyleBehavior), 
            defaultValue: null, 
            propertyChanged: OnAttachBehaviorChanged);

        public static object GetAttachBehavior(BindableObject view)
        {
            return (object)view.GetValue(AttachBehaviorProperty);
        }

        public static void SetAttachBehavior(BindableObject view, object value)
        {
            view.SetValue(AttachBehaviorProperty, value);
        }

        static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
        {
            Editor editor = view as Editor;
            if (editor == null)
            {
                return;
            }

            EventToCommandBehavior attachBehavior = newValue as EventToCommandBehavior;
            editor.Behaviors.Add(attachBehavior);
        }
    }

I am attaching event to my command but i dont understand how to get sender and event args inside my command. I need both of this arguments for my needs. I understand how to pass whole editor object or just model from data type but dont understand how to get event paramethers. Can u please explain how to do this?

1

There are 1 best solutions below

0
On BEST ANSWER

You can try to create a custom view for your Editor.

I achieved this function by inheriting parent class Entry. The same applies to Editor.

You can refer to the following code:

1.create a class MyEntry.cs and add necessary BindableProperty.

  public class MyEntry:Entry 
{
    public MyEntry()
    {
        this.TextChanged += this.OnTextChanged;
    }

    public static readonly BindableProperty TextChangedCommandProperty =
        BindableProperty.Create(nameof(MyEntry.TextChangedCommand), typeof(ICommand), typeof(Entry));

    public static readonly BindableProperty TextChangedCommandParameterProperty =
        BindableProperty.Create(nameof(MyEntry.TextChangedCommandParameter), typeof(object), typeof(Entry));

    public ICommand TextChangedCommand
    {
        get => (ICommand)this.GetValue(MyEntry.TextChangedCommandProperty);
        set => this.SetValue(TextChangedCommandProperty, (object)value);
    }

    public object TextChangedCommandParameter
    {
        get => this.GetValue(MyEntry.TextChangedCommandParameterProperty);
        set => this.SetValue(TextChangedCommandParameterProperty, value);
    }

    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        if (this.TextChangedCommand == null ||
             !this.TextChangedCommand.CanExecute(this.TextChangedCommandParameter))
            return;

        this.TextChangedCommand.Execute(this.TextChangedCommandParameter);
    }
}

2.created a viewmodel (MyViewModel.cs)

public class MyViewModel: INotifyPropertyChanged 
{

    string inputValue;
    public string InputValue
    {
        set { SetProperty(ref inputValue, value); }
        get { return inputValue; }
    }

    public ICommand TextChangedCommand { get; set; }

    public MyViewModel() {

        TextChangedCommand = new Command(testcommand);


    }
    private void testcommand(object obj)
    {
        if (obj!= null)
        {
            MyViewModel viewModel = obj as MyViewModel;

            Console.WriteLine("---> input string is = " + viewModel.InputValue);
        }
    }
    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

3.Usage example:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mauiApp0705="clr-namespace:MauiApp0705"
             x:Class="MauiApp0705.MainPage">

    <ContentPage.BindingContext>
        <mauiApp0705:MyViewModel></mauiApp0705:MyViewModel>
    </ContentPage.BindingContext>

        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

        <mauiApp0705:MyEntry 
           Text="{Binding InputValue}"
           HorizontalTextAlignment="Start"
           HorizontalOptions="FillAndExpand"
           VerticalOptions="Center"
           VerticalTextAlignment="Center"
           Keyboard='Text'
           ClearButtonVisibility="WhileEditing"
           TextChangedCommand="{Binding TextChangedCommand, Mode=OneTime}"
           TextChangedCommandParameter="{Binding Mode=OneTime}" >
        </mauiApp0705:MyEntry>

    </VerticalStackLayout>

</ContentPage>