Avalonia 11 - 如何将数据从 View 传递到 ViewModel(需要处理文本框上的焦点)

问题描述 投票:0回答:1

我正在开发一个触摸屏应用程序。 我在将 GotFocus 数据传递到 ViewModel 时遇到问题。我的按钮需要知道当前选择了哪个文本框 - 它将根据焦点更改 ViewModel 中的给定字符串。我正在使用社区 MVVM 工具包。

这是我的用户控件:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="using:TouchPanel.ViewModels"
             xmlns:views="clr-namespace:TouchPanel.Views"
             mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="600"
             x:Class="TouchPanel.Views.PickUpParcelView"
             x:DataType="vm:PickUpParcelViewModel">
    <Design.DataContext>
        <vm:PickUpParcelViewModel/>
    </Design.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="512" />
            <ColumnDefinition Width="512" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="0" VerticalAlignment="Center" Spacing="10" Margin="50">
            <TextBlock> Enter your phone number</TextBlock>
            <TextBox 
                Name="TextBoxPhoneNumber"
                Watermark="Ex. +00 123 456 789"
                Text="{Binding PhoneNumber}">
            </TextBox>
            <TextBlock> Enter your pick up code</TextBlock>
            <TextBox
                Name="TextBoxPickUpCode"
                Watermark="Ex. 42069"
                Text="{Binding PickUpCode}"
                GotFocus="TextBox_GotFocus"
                LostFocus="TextBox_LostFocus">
            </TextBox>
        </StackPanel>
        <StackPanel
            Grid.Column="1"
            Background="CadetBlue">
            <Button
                Command="{Binding AddLetterA}">
                Add Letter A
            </Button>
        </StackPanel>
    </Grid>
</UserControl>

UserControl.axaml.cs

using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using System;
using System.Diagnostics;
using TouchPanel.ViewModels;
namespace TouchPanel.Views;

public partial class PickUpParcelView : UserControl
{
    bool gotFocus = false;
    public TextBox selectedTextBox; // i want to pass this to my viewmodel to modify
    public PickUpParcelView()
    {
        InitializeComponent();
    }
    public void TextBox_GotFocus(object source, GotFocusEventArgs args)
    {
        Debug.WriteLine("Got Focus");
        selectedTextBox = (TextBox)source;
        gotFocus = true;
    }
    public void TextBox_LostFocus(object source, RoutedEventArgs args)
    {
        Debug.WriteLine("LostFocus");
        gotFocus = false; 
    }
}

视图模型

using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TouchPanel.ViewModels
{
    public partial class PickUpParcelViewModel : ViewModelBase
    {
        [ObservableProperty]
        public string? _pickUpCode = string.Empty;

        [ObservableProperty]
        public string? _phoneNumber = string.Empty;

        [RelayCommand]
        public void AddLetterA()
        {
            PickUpCode += "A";
        }
    }
}

我尝试查找了几个小时但无济于事,我找不到合适的解决方案来解决我的问题。 教程和示例似乎也没有很好的解决方案。

c# mvvm avaloniaui avalonia community-toolkit-mvvm
1个回答
0
投票

看来你违反了 MVVM。 但对于你的问题,请尝试这个:

景色

<TextBox 
        Name="TextBoxPhoneNumber"
        Watermark="Ex. +00 123 456 789"
        Text="{Binding PhoneNumber}">
        <Interaction.Behaviors>
            <EventTriggerBehavior
            EventName="GotFocus">
            <InvokeCommandAction
               Command="{Binding PhoneNumberGotFocusedCommand}"
               CommandParameter="{Binding ElementName=TextBoxPhoneNumber}"/>
            </EventTriggerBehavior>
         </Interaction.Behaviors>
</TextBox>
<TextBlock> Enter your pick up code</TextBlock>
<TextBox
        Name="TextBoxPickUpCode"
        Watermark="Ex. 42069"
        Text="{Binding PickUpCode}">
        <Interaction.Behaviors>
            <EventTriggerBehavior
                EventName="GotFocus">
                <InvokeCommandAction
                    Command="{Binding PickUpCodeGotFocusedCommand}"
                    CommandParameter="{Binding ElementName=TextBoxPickUpCode}"/>
            </EventTriggerBehavior>
         </Interaction.Behaviors>
 </TextBox>

视图模型

私人文本框? _focusedTextBox;

[RelayCommand]
private void PhoneNumberGotFocused(TextBox? textBox)
    => UpdateLastFocusedTextBox(textBox);

[RelayCommand]
private void PickUpCodeGotFocused(TextBox? textBox)
    => UpdateLastFocusedTextBox(textBox);

private void UpdateLastFocusedTextBox(TextBox? textBox)
{
    if (textBox?.IsFocused == true)
        _focusedTextBox = textBox;
}
© www.soinside.com 2019 - 2024. All rights reserved.