Reputation: 5276
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);
}
}
Upvotes: 1
Views: 719
Reputation: 65586
The issue appears to be related to code you haven't shown.
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.
Upvotes: 3
Reputation: 169420
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" };
Upvotes: 0