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");
}
我正在使用 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");
}