You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avalonia 11:如何将TextBox焦点数据从View传至ViewModel

解决Community MVVM Toolkit下TextBox焦点事件传递到ViewModel的问题

针对你需要将TextBox的GotFocus事件数据传递到ViewModel,实现按钮修改对应字符串的需求,这里提供两种符合MVVM原则的实现方案:


方案1:直接在XAML中绑定EventToCommand(推荐)

利用Avalonia的交互行为库,无需后台代码即可将事件绑定到ViewModel的命令,传递文本框标识来区分目标字段。

UserControl XAML 代码

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
             xmlns:cmd="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"
             x:Class="YourApp.YourUserControl">
  <StackPanel>
    <!-- 第一个文本框,用Tag标识对应ViewModel的FirstName属性 -->
    <TextBox Tag="FirstName" Text="{Binding FirstName}">
      <i:Interaction.Behaviors>
        <cmd:EventToCommand EventName="GotFocus" 
                            Command="{Binding SetActiveTextBoxCommand}"
                            CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Tag}"/>
      </i:Interaction.Behaviors>
    </TextBox>

    <!-- 第二个文本框,用Tag标识对应ViewModel的LastName属性 -->
    <TextBox Tag="LastName" Text="{Binding LastName}">
      <i:Interaction.Behaviors>
        <cmd:EventToCommand EventName="GotFocus" 
                            Command="{Binding SetActiveTextBoxCommand}"
                            CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Tag}"/>
      </i:Interaction.Behaviors>
    </TextBox>

    <Button Content="修改当前文本框内容" Command="{Binding ModifyActiveTextBoxCommand}"/>
  </StackPanel>
</UserControl>

ViewModel 代码(基于Community MVVM)

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public partial class YourViewModel : ObservableObject
{
    // 绑定文本框的字符串属性
    [ObservableProperty]
    private string _firstName = string.Empty;

    [ObservableProperty]
    private string _lastName = string.Empty;

    // 记录当前激活的文本框标识
    [ObservableProperty]
    private string _activeTextBoxTag = string.Empty;

    // 处理文本框获取焦点的命令
    [RelayCommand]
    private void SetActiveTextBox(string tag)
    {
        ActiveTextBoxTag = tag;
    }

    // 按钮触发的修改命令
    [RelayCommand]
    private void ModifyActiveTextBox()
    {
        switch (ActiveTextBoxTag)
        {
            case "FirstName":
                FirstName = "已修改的名字";
                break;
            case "LastName":
                LastName = "已修改的姓氏";
                break;
        }
    }
}

方案2:后台代码中转事件(适合需预处理场景)

如果需要在后台对事件数据做预处理,再传递到ViewModel:

UserControl.axaml.cs 代码

public partial class YourUserControl : UserControl
{
    public YourUserControl()
    {
        InitializeComponent();
        // 给所有目标文本框绑定焦点事件
        TxtFirstName.GotFocus += OnTextBoxGotFocus;
        TxtLastName.GotFocus += OnTextBoxGotFocus;
    }

    private void OnTextBoxGotFocus(object? sender, GotFocusEventArgs e)
    {
        if (sender is TextBox textBox && DataContext is YourViewModel vm)
        {
            // 传递文本框的Tag标识到ViewModel命令
            vm.SetActiveTextBoxCommand.Execute(textBox.Tag?.ToString());
        }
    }
}

ViewModel代码与方案1完全一致,仅通过后台中转事件触发命令。


关键注意事项

  1. 确保UserControl的DataContext已正确绑定到ViewModel(可在构造函数或父容器中设置DataContext = new YourViewModel();)
  2. 避免直接传递TextBox控件实例到ViewModel(违反MVVM分离原则),始终用标识(如Tag、Name)对应ViewModel中的属性
  3. 利用Community MVVM的[RelayCommand]特性自动生成命令属性,无需手动实例化RelayCommand

内容的提问来源于stack exchange,提问作者melancholy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:17:21