简体   繁体   English

如果以 xamarin 形式选择它,如何清除选择器?

[英]How to clear picker if It is selected in xamarin forms?

I have two picker.我有两个选择器。 second picker is dependent on first picker.第二个选择器取决于第一个选择器。 Both pickers are bind from Service.两个选择器都从服务绑定。 I am using dictionary object to bind data to picker.我正在使用字典对象将数据绑定到选择器。 I am not using MVVM pattern.我没有使用 MVVM 模式。

  1. First service call where dictionary object for first picker is bind.第一个服务调用,其中绑定了第一个选择器的字典对象。
  2. then fill first picker from that dictionary object.然后从该字典对象中填充第一个选择器。 At that time Second picker is empty.那时第二个选择器是空的。
  3. On selectedIndexChange event of first picker call service to bind dictionary object of second picker.在第一个选择器调用服务的 selectedIndexChange 事件上绑定第二个选择器的字典对象。
  4. Now Fill values to second picker from dictionary object.现在将值从字典对象填充到第二个选择器。 (If already picker has data then put Picker.Items.clear() ) (如果已经选择器有数据,则放置Picker.Items.clear()
  5. Now If I select some value from second picker and change value of first picker then It gives me error at Picker.Items.clear()现在,如果我从第二个选择器中选择一些值并更改第一个选择器的值,那么它会在Picker.Items.clear()处给我错误

System.ArgumentOutOfRangeException: Index was out of range. System.ArgumentOutOfRangeException:索引超出范围。 Must be non-negative and less than the size of the collection.必须是非负的并且小于集合的大小。

Parameter name: index参数名称:索引

Global Declaration :全球宣言:

Dictionary<string, string> DicObjActivityType;

Dictionary<string, string> DicObjSelfActivity;

First Picker selectedIndexChange event First Picker selectedIndexChange 事件

private async void PckrActivityType_SelectedIndexChanged(object sender, EventArgs e)
{
    if (sender as Picker == null)
        return;
    else
    {
        var objActivityType = sender as Picker;
        var Key = DicObjActivityType.FirstOrDefault(x => x.Value == objActivityType.Items[objActivityType.SelectedIndex]).Key;
        PickedActivityType = Key;
        if (Key != "0")
        {
            PckrSelfActivity.IsEnabled = true;
            await CallGetWebService_SelfActivity(Key);
            if (PckrSelfActivity.IsEnabled == true)
            {
                PckrSelfActivity.Items.Clear();
                foreach (string items in DicObjSelfActivity.Values)
                {
                    PckrSelfActivity.Items.Add(items);
                }
            }
        }
        else
        {
            PckrSelfActivity.IsEnabled = false;
        }
    }
}

Call Service of second picker呼叫第二拣货员服务

private async Task CallGetWebService_SelfActivity(string strkey)
{
    try
    {
        var response = await GetResponseFromWebService.GetResponse<ServiceClasses.RootObject_LstListComboData>(ServiceURL.GetSelfActivity + "ActivityTypeCd=" + strkey);

        if (response.Flag == true)
        {
            DicObjSelfActivity = new Dictionary<string, string>();
            DicObjSelfActivity.Add("0", "--Select--");
            if (response.lstListComboData != null)
            {
                foreach (ServiceClasses.LstListComboData Items in response.lstListComboData)
                {
                    DicObjSelfActivity.Add(Items.Value, Items.Text);
                }
            }
        }
        else
        {
            PckrSelfActivity.IsEnabled = false;
        }
    }
    catch (Exception e)
    {
        await DisplayAlert(AppResources.LError, AppResources.LConnectionError, "OK");
    }
}

I refer following link to solve this issue我参考以下链接来解决这个问题

https://forums.xamarin.com/discussion/55922/picker-clear-system-argumentoutofrangeexception https://forums.xamarin.com/discussion/55922/picker-clear-system-argumentoutofrangeexception

but didn't find solution.但没有找到解决方案。

We can't clear picker if any of the value is selected?如果选择了任何值,我们无法清除选择器?

I don't want to use BindablePicker cutom control.我不想使用 BindablePicker 自定义控件。

I'm not sure if by "clear the picker" you mean reset it such that it doesn't show any items as selected.我不确定“清除选择器”是否是指重置它,使其不显示任何已选择的项目。 But if that's what you want, then you can do the following:但是,如果这就是您想要的,那么您可以执行以下操作:

  1. Set SelectedIndex = -1 .设置SelectedIndex = -1 This resets the picker such that no items are selected.这将重置选择器,以便不选择任何项目。

  2. Once you set SelectedIndex = -1 , the selectedIndexChange event handler is called, and that's causing the设置SelectedIndex = -1 ,将调用selectedIndexChange事件处理程序,这将导致

System.ArgumentOutOfRangeException: Index was out of range. System.ArgumentOutOfRangeException:索引超出范围。 Must be non-negative and less than the size of the collection.必须是非负的并且小于集合的大小。

Indeed yes, the SelectedIndex is -1 , so it's complaining that the index must be non-negative.确实是的, SelectedIndex-1 ,所以它抱怨索引必须是非负的。

  1. To avoid the ArgumentOutOfRangeException, add an if statement that encloses your SelectedIndexChange event handler so that the handler only executes为避免 ArgumentOutOfRangeException,请添加一个包含SelectedIndexChange事件处理程序的if语句,以便处理程序仅执行
    if (SelectedIndexChange != -1) . if (SelectedIndexChange != -1)

In summary, do this:总之,这样做:

YourPicker.SelectedIndex = -1;
YourPicker.SelectedIndexChanged += (sender, e) =>
{
    if (YourPicker.SelectedIndex != -1)
    {
        //Do your stuff
    }
}

I think you receive this error because you clean all items in the picker.我认为您收到此错误是因为您清理了选择器中的所有项目。 I had the same error but I'm using now MVVM, it's more simple and you can manage this kind of thing better.我有同样的错误,但我现在使用的是 MVVM,它更简单,你可以更好地管理这种事情。

Actually i do the following and it is working fine for me:实际上我做了以下工作,它对我来说很好:

//step 1: re-select index to -1
YourPicker.SelectedIndex = -1;
//step 2: clear all items
YourPicker.Items.Clear();
//refill the picker 
foreach (var item in subAccountStatus)
{
    YourPicker.Items.Add(item.AccountStatus);                  
}
//re-selected index to first item
YourPicker.SelectedIndex = 0;

Now that the Picker class uses bindings, you can bind a List of strings to the picker using the ItemSource attribute.现在Picker类使用绑定,您可以使用ItemSource属性将字符串List绑定到选择器。 What I did to fix this issue in my apps is I created a helper method called GeneratePickerSource()我在应用程序中为解决此问题所做的是创建了一个名为GeneratePickerSource()的辅助方法

This is my Picker in XAML:这是我在 XAML 中的Picker

<Picker x:Name="myPicker" Title="Placeholder"/>

Then my GeneratePickerSource() method:然后我的GeneratePickerSource()方法:

List<string> pickerStrings = new List<string>();

//Add your picker options to the list

myPicker.ItemSource = pickerStrings;

By using this method, whenever you call GeneratePickerSource() , the Picker will be reset and there will be no selected item (for myPicker , it will show "Placeholder" since that is its Title ).通过使用此方法,每当您调用GeneratePickerSource() ,Picker 将被重置并且不会有被选中的项目(对于myPicker ,它将显示“Placeholder”,因为这是它的Title )。

This solution works well if your list is short, which is most likely the case.如果您的列表很短,则此解决方案效果很好,这很可能是这种情况。 But this may be slow if you have a very, very large list you need to generate each time.但是,如果您每次都需要生成一个非常非常大的列表,这可能会很慢。

In your case, you can do the same thing with the Dictionary as I did with the List , simply create a new Dictionary , fill it, and set it as the ItemSource .在您的情况下,您可以对Dictionary做与我对List做的相同的事情,只需创建一个新的Dictionary ,填充它,并将其设置为ItemSource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM