C# 为什么此选择器未按预期选择项目?

C# 为什么此选择器未按预期选择项目?,c#,xamarin,picker,C#,Xamarin,Picker,我正在尝试使用选择器从列表中加载ItemSource,并根据外部事件,根据Local.id更改其SelectedIndex,但到目前为止我一直尝试的方法不起作用 C#代码: 公共类本地 { 公共字符串ciade{get;set;} 公共int id{get;set;} } 公共整数索引{get;set;} 字符串jsonCidades; 公共异步void CarregaCidades() { 尝试 { 使用(WebClient browser=新WebClient()) { Uri uriCid

我正在尝试使用选择器从列表中加载ItemSource,并根据外部事件,根据Local.id更改其SelectedIndex,但到目前为止我一直尝试的方法不起作用

C#代码:

公共类本地
{
公共字符串ciade{get;set;}
公共int id{get;set;}
}
公共整数索引{get;set;}
字符串jsonCidades;
公共异步void CarregaCidades()
{
尝试
{
使用(WebClient browser=新WebClient())
{
Uri uriCidades=新Uri(“xxxxxxx.php”);
jsonCidades=await browser.downloadstringtasksync(uriCidades);
}
var ListaCidades=Newtonsoft.Json.JsonConvert.DeserializeObject(jsonCidades);
PickerCidades.ItemsSource=ListaCidades;
}
捕获(例外)
{
投掷;
}
}
//在执行的某个时刻,此代码被调用:
Local localizacao=JsonConvert.DeserializeObject(json);
if(localizacao.GetType().GetProperty(“id”)!=null)
{
/*cidadeditem=本地化;
我以前用SelectedItem=“{Binding-editem,Mode=TwoWay}”尝试过这个方法*/
cidadeseledindex=localizacao.id;//正在尝试此操作
}
在尝试使用ItemDisplayBinding=“{Binding ListaCidades.cidade,Mode=OneWay}”进行绑定之前,由于它不起作用,我开始使用ItemSources=ListaCidades

我的XAML代码:

<Picker x:Name="PickerCidades"
        SelectedIndex="{Binding CidadeSelectedIndex, Mode=TwoWay}"
        Grid.Column="1" Grid.Row="0"
        SelectedIndexChanged="PickerCidades_SelectedIndexChanged">
</Picker>


我认为它不起作用,因为我正在使用ItemsSource设置项目。我想我需要用xaml绑定它。如果您的目标是从代码更改用户界面,那么您需要一个实现INotifyPropertyChanged(或从实现INotifyPropertyChanged的基础继承)的ViewModel。然后将SelectedIndex绑定属性改为简单的get;设置如下,它将触发PropertyChanged事件

public int CidadeSelectedIndex{ get; set; }
需要触发通知事件。类似这样的东西

public class MyViewModel : INotifyPropertyChanged  
{  

    public event PropertyChangedEventHandler PropertyChanged;  

    // This method is called by the Set accessor of each property.  
    // The CallerMemberName attribute that is applied to the optional propertyName  
    // parameter causes the property name of the caller to be substituted as an argument.  
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")  
    {  
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }  

    private int _cidadeSelectedIndex;

    public int CidadeSelectedIndex
    {
        get => _cidadeSelectedIndex;
        set {
            _cidadeSelectedIndex = value;
            NotifyPropertyChanged();
        }
    }
}  

你想达到下面的效果吗?

我的xaml布局类似于下面的代码

    <StackLayout>
    <!-- Place new controls here -->
    <Picker x:Name="PickerCidades"
            ItemsSource="{ Binding locals}"
            SelectedIndex="{Binding CidadeSelectedIndex, Mode=TwoWay}"

            ItemDisplayBinding="{Binding cidade}" 
            Grid.Column="1" Grid.Row="0"
            SelectedIndexChanged="PickerCidades_SelectedIndexChanged">


    </Picker>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />

        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Label Text="CidadeSelectedIndex: " Grid.Column="0" Grid.Row="0"/>
        <Label Text="{Binding CidadeSelectedIndex}" Grid.Column="1" Grid.Row="0"/>
    </Grid>

</StackLayout>
MyViewMode代码。我使用静态数据进行测试。您可以实现
INotifyPropertyChanged
界面进行动态更改

    public  class MyViewModel : INotifyPropertyChanged
{


    int _cidadeSelectedIndex=1;
    public int CidadeSelectedIndex
    {
        set
        {
            if (_cidadeSelectedIndex != value)
            {
                _cidadeSelectedIndex = value;
                OnPropertyChanged("CidadeSelectedIndex");

            }
        }
        get
        {
            return _cidadeSelectedIndex;
        }
    }
    public ObservableCollection<Local> locals { get; set; }

    public MyViewModel()
    {
        locals = new ObservableCollection<Local>();

        locals.Add(new Local() { cidade=  "xxx0"  , id=  0 });
        locals.Add(new Local() { cidade = "xxx1", id = 1 });
        locals.Add(new Local() { cidade = "xxx2", id = 2 });
        locals.Add(new Local() { cidade = "xxx3", id = 3 });
        locals.Add(new Local() { cidade = "xxx4", id = 4 });

    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
公共类MyViewModel:INotifyPropertyChanged
{
int_=1;
公共整数索引
{
设置
{
如果(_=dedix!=值)
{
_指数=数值;
OnPropertyChanged(“CideDeclatedIndex”);
}
}
得到
{
返回索引;
}
}
公共可观测集合局部变量{get;set;}
公共MyViewModel()
{
局部变量=新的可观测集合();
Add(new Local(){cidade=“xxx0”,id=0});
Add(new Local(){cidade=“xxx1”,id=1});
Add(new Local(){cidade=“xxx2”,id=2});
Add(newlocal(){cidade=“xxx3”,id=3});
Add(newlocal(){cidade=“xxx4”,id=4});
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}

您是否正在使用INotifyPropertyChanged?否。我正在调用一个方法,该方法会更改取消选择的索引的值。如果您不使用INotifyPropertyChanged,则更改所选索引变量的值不会更新UIINPC@Jason如果我使用“INPC”,是否可以通过更改SelectedIndex来更改ui?@Sandro Benevides此问题是否有任何更新?如果回复有帮助,请将其标记为答案,它将帮助其他有类似问题的人。
    public partial class MainPage : ContentPage
{
    MyViewModel myViewModel;
    public MainPage()
    {
        InitializeComponent();
         myViewModel=  new MyViewModel();
        BindingContext = myViewModel;
    }

    private void PickerCidades_SelectedIndexChanged(object sender, EventArgs e)
    {

        var picker = (Picker)sender;
        int selectedIndex = picker.SelectedIndex;

        myViewModel.CidadeSelectedIndex = selectedIndex;

    }
}
    public  class MyViewModel : INotifyPropertyChanged
{


    int _cidadeSelectedIndex=1;
    public int CidadeSelectedIndex
    {
        set
        {
            if (_cidadeSelectedIndex != value)
            {
                _cidadeSelectedIndex = value;
                OnPropertyChanged("CidadeSelectedIndex");

            }
        }
        get
        {
            return _cidadeSelectedIndex;
        }
    }
    public ObservableCollection<Local> locals { get; set; }

    public MyViewModel()
    {
        locals = new ObservableCollection<Local>();

        locals.Add(new Local() { cidade=  "xxx0"  , id=  0 });
        locals.Add(new Local() { cidade = "xxx1", id = 1 });
        locals.Add(new Local() { cidade = "xxx2", id = 2 });
        locals.Add(new Local() { cidade = "xxx3", id = 3 });
        locals.Add(new Local() { cidade = "xxx4", id = 4 });

    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}