【问题标题】:Xamarin.Forms set focus from mvvm ViewModelXamarin.Forms 从 mvvm ViewModel 设置焦点
【发布时间】:2017-06-29 19:02:16
【问题描述】:

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

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

我如何在 Android 和 iOS 上做到这一点?

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

更新:

在页面类中:

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

在模型类中:

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

}

【问题讨论】:

  • 那么,无论如何,你要不要把重点放在入口上?
  • 我想在单击按钮时重新设置焦点或保持焦点在条目上,但是当用户点击消息时,例如,键盘应该隐藏。

标签: c# xamarin xamarin.forms freshmvvm


【解决方案1】:

这是我如何做的一个例子,在此之前我曾经使用 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");
    }

【讨论】:

    【解决方案2】:

    这可以通过在 PCL 中使用 FindByName&lt;&gt;() 函数轻松实现。
    这是这样做的一种方法:

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

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

    编辑:

    在您的情况下,我认为您的问题是您的条目设置为private,因此我建议将其公开为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:

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

    在您正在创建的页面内:

    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,因为我没有您的自定义条目的所有实现。

    【讨论】:

    • 我不使用事件处理程序。我使用 mvvm 命令进行数据绑定。
    • 我试过了。我收到错误“此元素不在名称范围内”
    • 能否请您展示您是如何创建条目的?请问您是如何包含我展示的两行代码的。
    • @Atlantis 根据您更新的问题更新了答案。希望这行得通。
    • 不幸的是,没有任何改变。同样的例外。
    猜你喜欢
    • 2011-07-17
    • 2023-01-07
    • 1970-01-01
    • 2020-10-14
    • 2015-11-19
    • 1970-01-01
    • 2013-02-28
    • 2015-09-19
    • 1970-01-01
    相关资源
    最近更新 更多