[英]How do I set focus on a Picker after selecting an item from another Picker using Prism and the MVVM way?
Scenario Two invisible but enabled pickers. 方案两个不可见但已启用的选择器。 One is for org.units, the other is for the users in the selected org.unit.
一个用于org.units,另一个用于所选org.unit中的用户。 The first picker is focused when the user taps on an Add (plus sign) in the ToolBar.
当用户点击工具栏上的“添加”(加号)时,第一个选择器将聚焦。 When the user chooses an org.unit I need to set focus on the other picker.
当用户选择org.unit时,我需要将重点放在另一个选择器上。
Problem After selecting an orgunit it will not set the focus on the user picker. 问题选择组织单位后,它不会将焦点放在用户选择器上。
XAML XAML
<Picker
x:Name="PickerOrgUnit"
Title="Select an organization unit"
IsEnabled="True"
IsVisible="False"
ItemDisplayBinding="{Binding OrgUnitName}"
ItemsSource="{Binding OrgUnits, Mode=TwoWay}"
SelectedIndexChanged="PickerOrgUnit_SelectedIndexChanged"
SelectedItem="{Binding SelectedOrgUnit}"
Style="{StaticResource PagePicker}">
<Picker.Behaviors>
<b:EventToCommandBehavior
Command="{Binding PickerOrgUnitItemChangedCommand}"
CommandParameter="{x:Reference PickerOrgUnit}"
EventName="SelectedIndexChanged" />
</Picker.Behaviors>
</Picker>
<Picker
x:Name="PickerUser"
Title="Select a user"
IsEnabled="True"
IsVisible="False"
ItemsSource="{Binding Users, Mode=TwoWay}"
SelectedIndexChanged="PickerUser_SelectedIndexChanged"
SelectedItem="{Binding SelectedUser}"
Style="{StaticResource PagePicker}">
<Picker.Behaviors>
<b:EventToCommandBehavior
Command="{Binding PickerUserItemChangedCommand}"
CommandParameter="{x:Reference PickerUser}"
EventName="SelectedIndexChanged" />
</Picker.Behaviors>
</Picker>
Datamodels (simplified for easier readibility) 数据模型 (经过简化以提高可读性)
public class OrgUnitModel
{
public int OrgUnitID { get; set; }
public string OrgUnitName { get; set; }
}
// Users here are handled in a multi-used code, named ListModel
public class ListModel
{
public int ListID { get; set; }
public string ListName { get; set; }
}
Code behind XAML XAML背后的代码
private void PickerOrgUnit_SelectedIndexChanged(object sender, System.EventArgs e)
{
var vm = BindingContext as FYIUsersPageViewModel; // this is a viemodel which handles a list of users, see below
if (vm == null) return;
var vmCommand = vm.PickerOrgUnitChangedCommand;
if (vmCommand.CanExecute(sender))
vmCommand.Execute(sender);
}
private void PickerUser_SelectedIndexChanged(object sender, System.EventArgs e)
{
...
}
ViewModel (simplified) ViewModel (简体)
public class FYIUsersPageViewModel : BindableBase, INavigationAware
{
public DelegateCommand<object> PickerOrgUnitChangedCommand => new DelegateCommand<object>(PickerOrgUnitChangedMethod);
public DelegateCommand<object> PickerUserChangedCommand => new DelegateCommand<object>(PickerUserChangedMethod);
private UserModel selectedOrgUnit;
public UserModel SelectedOrgUnit { get => selectedOrgUnit; set { selectedOrgUnit = value; RaisePropertyChanged("SelectedOrgUnit"); } }
private UserModel selectedUser;
public UserModel SelectedUser { get => selectedUser; set { selectedUser = value; RaisePropertyChanged("SelectedUser"); } }
public ObservableCollection<OrgUnitModel> OrgUnits { get; set; } // orgunits
public ObservableCollection<ListModel> Users { get; set; } // users in an orgunit
// constructor
public FYIUsersPageViewModel(INavigationService navigationService)
{
NavigationService = navigationService;
LoadOrgUnits(); // loads all orgunits into OrgUnits from DB
}
// code for calling OrgUnit picker, not relevant
...
//
public void PickerOrgUnitChangedMethod(object obj)
{
OrgUnitModel selItem = (OrgUnitModel)((Picker)obj).SelectedItem;
if (selItem == null)
return;
LoadUsers(selItem.OrgUnitID); // load orgunit users from DB
Picker picker = (Picker)obj;
// THIS IS WHAT DOES NOT WORK! Because I call the orgunit picker here, not the user picker... HELP NEEDED HERE!
Device.BeginInvokeOnMainThread(() =>
{
if (picker.IsFocused)
picker.Unfocus();
picker.Focus();
});
picker.Focus();
}
public void PickerUserChangedMethod(object obj)
{
// Goal reached, do something with the selected user.
// BUT I NEVER GET HERE!
}
}
Solution: Use this in the SelectedIndexChanged event of the first picker (PickerOrgUnit): 解决方案:在第一个选择器(PickerOrgUnit)的SelectedIndexChanged事件中使用此函数:
this.FindByName<Picker>("PickerUser").Focus();
where "PickerUser" is the name of the second picker. 其中“ PickerUser”是第二个选择器的名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.