Xamarin.Forms 从 mvvm ViewModel 设置焦点

Xamarin.Forms set focus from mvvm ViewModel

我正在使用 Xamarin.Forms 开发聊天应用程序。

并且我想避免在 Entry 失去焦点并单击发送按钮时隐藏键盘。

如何在 Android 和 iOS 上完成?

我使用 XF,完整的 Mvvm 没有 XAML(仅 C#)

更新:

在第 class 页中:

private EntrySetBorder _newMessageEntry;
...
_newMessageEntry = new EntrySetBorder
{
    TextColor = Color.Black,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.End,
    Margin = new Thickness(0, 0, 5, 0)
};

模型 class:

var entry = CurrentPage.FindByName<EntrySetBorder>("_newMessageEntry");
entry.Focus();

}

这可以通过使用 PCL 中的 FindByName<>() 函数轻松实现。
这是一种方法:

Entry myEntry = CurrentPage.FindByName<Entry>("YourEntryName");
myEntry.Focus();

您可以将其添加到发送按钮的点击处理程序的末尾。

编辑:

在您的情况下,我认为您的问题是您的条目设置为 private,因此我建议将其公开为 public 或使用另一个 public 属性。两个可能有效的解决方案:

public EntrySetBorder _newMessageEntry;
...
_newMessageEntry = new EntrySetBorder
{

    TextColor = Color.Black,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.End,
    Margin = new Thickness(0, 0, 5, 0)
};

并且:

EntrySetBorder entry = CurrentPage.FindByName<EntrySetBorder>("_newMessageEntry");
entry.Focus();

或者你这样做:

private EntrySetBorder _newMessageEntry;
...
_newMessageEntry = new EntrySetBorder
{

    TextColor = Color.Black,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.End,
    Margin = new Thickness(0, 0, 5, 0)
};
public EntrySetBorder NewMessageEntry => _newMessageEntry;

和:

EntrySetBorder entry = CurrentPage.FindByName<EntrySetBorder>("NewMessageEntry");
entry.Focus();

请试试:)

编辑 2:

在检查您的代码并对其进行测试后,最终修复它的方法是将 Entry 作为参数发送到您正在使用的命令中,例如:

在您正在创建的页面内:

sendButton.CommandParameter = NewMessageEntry; // We're adding the Entry we want to focus as a command parameter.

在您的 PageModel 和我们要使用的命令中:

public Command SendCommand
{
    get
    {
        return new Command<Entry>((obj) => //obj here means the parameters we're sending I.E: the entry we set it in the page.
        {
            //The code you want to execute
            Entry entry = obj;
            entry.Focus();
        });
    }
}

请注意,我使用了 Entry,因为我没有实现您的自定义条目的所有内容。

这是我如何做的一个例子,在此之前我曾经使用 MessagingCenter

在xaml中,你需要给你想要聚焦的obj一个x:Name。

<!-- PICKER's DEFINITION -->
<DatePicker
    x:Name="Datepicker"
    Date="{Binding SelectedDate, Mode=TwoWay}"
    IsEnabled="true"
    IsVisible="false">
</DatePicker>

然后您必须在按钮上的命令参数中引用该控件,或者例如在这种情况下我使用工具栏项。

<!-- MENU TOOLBAR -->
<ContentPage.ToolbarItems>
    <ToolbarItem
        Command="{Binding ShowCalendarCommand}"
        Icon="Calendar"
        CommandParameter="{x:Reference Datepicker}" />
</ContentPage.ToolbarItems>

然后在您的 vm 命令中:

    #region toolbar commands

    public ICommand ShowCalendarCommand => new RelayCommand<Object>(ShowCalendar);

    #endregion

    private void ShowCalendar(Object obj)
    {
        var calendar = (DatePicker)obj;
        calendar.Focus();
        //  MessagingCenter.Send(this, "Calendar");
    }