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?
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>