Maui事件控制行为如何在命令内获取发送者和参数?

huangapple go评论156阅读模式
英文:

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

问题

以下是您代码的翻译:

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);
    }
}

如果您想要了解如何在您的命令中获取发送者(sender)和事件参数(event args),请参考以下的说明:

EventToCommandBehavior 中,您定义了 EventNameCommand 属性。事件的发送者(sender)通常是触发事件的对象,而事件参数(event args)包含了事件的相关信息。

在您的 EditorTextChanged 命令中,TestQuestion 参数是您希望传递的模型对象。要在命令中获取事件的发送者和事件参数,您可以稍微修改命令签名:

[RelayCommand]
public void EditorTextChanged(object sender, TextChangedEventArgs e)
{
    // 您可以在这里访问 sender(发送者)和 e(事件参数)
    Editor editor = sender as Editor;
    if (editor != null)
    {
        // 在这里使用 editor 和 e 来获取所需的信息
        var text = editor.Text;
        // 其他操作
    }

    // 然后执行您的 ChangeHtml 方法
    ChangeHtml((TestQuestion)editor.BindingContext);
}

通过这种方式,您可以访问事件的发送者 sender 和事件参数 e,并且还可以使用 editor.BindingContext 获取与 Editor 相关联的模型对象。

英文:

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

得分: 0

你可以尝试为你的编辑器创建一个自定义视图。

我通过继承父类 Entry 来实现这个功能。对编辑器也是一样的。

你可以参考以下代码:

  1. 创建一个名为 MyEntry.cs 的类并添加必要的 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);
    }
}
  1. 创建一个视图模型 (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("---> 输入字符串为 = " + 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;
}
  1. 使用示例:
<?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>
英文:

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 =&gt; (ICommand)this.GetValue(MyEntry.TextChangedCommandProperty);
        set =&gt; this.SetValue(TextChangedCommandProperty, (object)value);
    }

    public object TextChangedCommandParameter
    {
        get =&gt; this.GetValue(MyEntry.TextChangedCommandParameterProperty);
        set =&gt; 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(&quot;---&gt; input string is = &quot; + viewModel.InputValue);
        }
    }
    bool SetProperty&lt;T&gt;(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:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; 
&lt;ContentPage xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
             xmlns:mauiApp0705=&quot;clr-namespace:MauiApp0705&quot;
             x:Class=&quot;MauiApp0705.MainPage&quot;&gt;

    &lt;ContentPage.BindingContext&gt;
        &lt;mauiApp0705:MyViewModel&gt;&lt;/mauiApp0705:MyViewModel&gt;
    &lt;/ContentPage.BindingContext&gt;

        &lt;VerticalStackLayout
            Spacing=&quot;25&quot;
            Padding=&quot;30,0&quot;
            VerticalOptions=&quot;Center&quot;&gt;

        &lt;mauiApp0705:MyEntry 
           Text=&quot;{Binding InputValue}&quot;
           HorizontalTextAlignment=&quot;Start&quot;
           HorizontalOptions=&quot;FillAndExpand&quot;
           VerticalOptions=&quot;Center&quot;
           VerticalTextAlignment=&quot;Center&quot;
           Keyboard=&#39;Text&#39;
           ClearButtonVisibility=&quot;WhileEditing&quot;
           TextChangedCommand=&quot;{Binding TextChangedCommand, Mode=OneTime}&quot;
           TextChangedCommandParameter=&quot;{Binding Mode=OneTime}&quot; &gt;
        &lt;/mauiApp0705:MyEntry&gt;

    &lt;/VerticalStackLayout&gt;

&lt;/ContentPage&gt;

huangapple
  • 本文由 发表于 2023年7月4日 22:15:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613536.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定