I am having an issue with trying to bind a ComboBox
in WinRT. I am using Prism/MVVM. I am able to bind the ItemsSource
to an ObservableCollection
no problem, and the ComboBox
is being populated.
What I am having trouble with, is having it automatically select the appropriate value based on the current Invoice
. Here is the relevant XAML:
<ComboBox Grid.Row="0" Grid.Column="1" Height="30"
ItemsSource="{Binding Path=Payees}"
DisplayMemberPath="AccountName"
SelectedValuePath="PayeeId"
SelectedValue="{Binding CurrentInvoice.PayeeId, Mode=TwoWay}"
Margin="5,0,10,0" />
Payees
is my ObservableCollection
and CurrentInvoice
is a property on the ViewModel
that points to the currently loaded Invoice
item. The Invoice
has a property called PayeeId
, which as you may guess, is the Id
of the Payee
that this Invoice
is associated to.
For some reason, no matter which Invoice
I select, the ComboBox
is blank when I navigate to my page. By blank, I just mean there is nothing selected, but it is populated with the Payees
collection.
If I manually change the selection, and save my Invoice
, the PayeeId
isn't changed. I think that it probably has something to do with the binding on the SelectedValue
, but so far I have been unable to figure this one out. Thanks in advance for any help!
Here are the properties for the Payees
and CurrentInvoice
:
private Invoice _currentInvoice;
public Invoice CurrentInvoice {
get { return _currentInvoice; }
set { SetProperty(ref _currentInvoice, value); }
}
private ObservableCollection<Payee> _payees;
public ObservableCollection<Payee> Payees
{
get { return _payees; }
set { SetProperty(ref _payees, value); }
}
EDIT:
I have added a property on the ViewModel
called SelectedPayee
that is bound to the SelectedItem
property of the ComboBox
. Here is the updated definition:
<ComboBox Grid.Row="0" Grid.Column="1" Height="30"
ItemsSource="{Binding Path=Payees}"
DisplayMemberPath="AccountName"
SelectedValuePath="Id"
SelectedItem="{Binding Path=SelectedPayee, Mode=TwoWay}"
Margin="5,0,10,0" />
When I select a Payee
and save, it saves with the new PayeeId
, but when I load the page it still does not load with the SelectedPayee
displayed in the ComboBox
. However, all is well in the designer. To further test, I have added a TextBox
that is bound to SelectedPayee.Id
:
<TextBox Grid.Row="7" Grid.Column="1" Text="{Binding Path=SelectedPayee.Id}" />
That displayed the correct number at design time and runtime, and is updated appropriately whenever I change the selection in the ComboBox
. The only thing that is not working correctly is the ComboBox
is not correctly displaying the Payee
AccountName
when I navigate to the page. As I said, the design view is correctly displaying the dummy data that I have in my designer ViewModel
. Is there something special about a ComboBox
that I am perhaps doing something in the wrong order?
EDIT 2:
I also am getting the exact same results using
SelectedValue={Binding Path=SelectedPayee.Id, Mode=TwoWay}
The binding is displaying the correct Payee.Id
in the TextBox
depending on which Payee
is selected in the ComboBox
, but it just does not display the SelectedPayee
when I first navigate to the page (but the TextBox
will be populated with the correct Id
.) This is really a head scratcher to me....
EDIT 3:
I got it all straightened out. The final issue I had going was I was setting the SelectedPayee
before actually loading the ComboBox
, so there was no property changes to trigger the SelectedValue
of the ComboBox
to change. Once I moved the call to LoadPayees()
above the assignment to SelectedValue
, everything works like a charm. See answer below.
For anyone who stumbles upon this question looking for a solution, what I ended up finding out was that I was setting the SelectedPayee
before loading the ComboBox
. I moved the call to LoadPayees()
up above the SelectedPayee
assignment, and now everything works as expected! Here is my OnNavigatedTo()
method for anyone interested:
public override async void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode,
Dictionary<string, object> viewModelState)
{
_headerViewModel.PageTitle = "Invoice Details";
await LoadPayees();
if (navigationParameter is Invoice)
{
_isEditing = true;
CurrentInvoice = navigationParameter as Invoice;
var payee = await _payeesRepository.LoadByIdAsync(CurrentInvoice.PayeeId);
SelectedPayee = payee;
await LoadPayments();
}
else
{
CurrentInvoice = new Invoice
{
CreationDate = DateTime.Now,
InvoiceDate = DateTime.Now,
Frequency = "M"
};
}
/* await LoadPayees(); was originally down here... oops! */
base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
}
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.