简体   繁体   中英

ComboBox SelectedItem not set with x:Bind

I'm trying to figure out why I can't set the initial SelectedItem value on my ComboBox if I bind with ItemsSource="{x:Bind [source]}" .
This xaml works

<ComboBox 
        ItemsSource="{Binding Sites, Mode=OneWay}"
        SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}"/> 

But when I change to the following xaml, the ComboBox contains the sites, but does not show the SelectedItem as the default. (In fact, it appears to flicker into view and then disappear).

<ComboBox 
        ItemsSource="{x:Bind ViewModel.Sites, Mode=OneWay}"
        SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}"/>

Here is the relevant code in the ViewModel. (I abbreviated the long Sites list.)

public List<string> Sites
{
    get
    {
        return new List<string>()
        {                
            "Miami",                
            "Texas"
        };
    }
}

private string _selectedContractSite = "Texas";
public string SelectedContractSite
{
    get
    {
        return _selectedContractSite;
    }
    set
    {
        Set(ref _selectedContractSite, value);
    }
}

Thanks for the help!

The issue appears to be related to code you haven't shown. (For future reference please see https://stackoverflow.com/help/mcve to remove guesswork in answering future questions.)

If I create a viewModel like this

public class ViewModel : INotifyPropertyChanged
{
    public List<string> Sites
    {
        get
        {
            return new List<string>()
            {
                "Miami",
                "Texas"
            };
        }
    }

    private string _selectedContractSite = "Texas";

    public string SelectedContractSite
    {
        get
        {
            return _selectedContractSite;
        }
        set
        {
            if (_selectedContractSite != value)
            {
                _selectedContractSite = value;
                OnPropertyChanged(nameof(SelectedContractSite));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

and then set up the codebehind like this:

    public MainPage()
    {
        this.InitializeComponent();

        this.ViewModel = new ViewModel();
    }

    public ViewModel ViewModel { get; set; }

Then the following XAML works as expected

<ComboBox ItemsSource="{x:Bind ViewModel.Sites, Mode=OneWay}"
          SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}" />

Note. I'm using x:Bind and referencing the ViewModel in both binding paths.

I suspect your confusion lies in the differences between x:Bind and Binding .
With x:Bind the root of the binding path is the page the control with the binding is on.
With Binding the root of the binding path is the DataContext of the page the control is on.
Mixing the two can get confusing. If you do need to use a combination of the two then set this.DataContext = this; in the page constructor so they both point to the same thing.

Why are you creating a new List<string> in the getter of the Sites property?

Try to create the source collection only once :

public List<string> Sites { get; } = new List<string>() { "Miami", "Texas" };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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