在使用Prism和MVVM方式从另一个选取器中选择一个项目之后,如何将重点放在选取器上?

时间:2019-06-28 08:25:25

标签: c# xaml xamarin visual-studio-2017 picker

场景 两个不可见但启用的选择器。一个用于org.units,另一个用于所选org.unit中的用户。当用户点击工具栏上的“添加”(加号)时,第一个选择器将聚焦。 当用户选择组织单位时,我需要将重点放在另一个选择器上。

问题:选择组织单位后,它不会将焦点放在用户选择器上。

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>

数据模型(为简化可读性而进行了简化)

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; }
}

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 (简体)

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!
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案: 在第一个选择器(PickerOrgUnit)的SelectedIndexChanged事件中使用它:

this.FindByName<Picker>("PickerUser").Focus();

其中“ PickerUser”是第二个选择器的名称。