在 WinRT 中对 ComboBox 的 SelectedValue 进行数据绑定 Prism/MVVM
DataBinding a ComboBox's SelectedValue in WinRT Prism/MVVM
我在尝试在 WinRT 中绑定 ComboBox
时遇到问题。我正在使用 Prism/MVVM。我可以将 ItemsSource
绑定到 ObservableCollection
没问题,并且正在填充 ComboBox
。
我遇到的问题是,它会根据当前 Invoice
自动 select 适当的值。这是相关的 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
是我的 ObservableCollection
,CurrentInvoice
是 ViewModel
上的 属性,指向当前加载的 Invoice
项目。 Invoice
有一个名为 PayeeId
的 属性,您可能会猜到,它是 Payee
的 Id
,与此 Invoice
关联.
出于某种原因,无论我 select 是哪个 Invoice
,当我导航到我的页面时,ComboBox
都是空白的。空白,我的意思是没有任何 selected,但它填充了 Payees
集合。
如果我手动更改 selection,并保存我的 Invoice
,PayeeId
不会更改。我认为这可能与 SelectedValue
上的绑定有关,但到目前为止我一直无法弄清楚这一点。在此先感谢您的帮助!
以下是 Payees
和 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); }
}
编辑:
我在名为 SelectedPayee
的 ViewModel
上添加了一个 属性,它绑定到 ComboBox
的 SelectedItem
属性。这是更新后的定义:
<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" />
当我 select 一个 Payee
并保存时,它保存了新的 PayeeId
,但是当我加载页面时它仍然没有加载 SelectedPayee
显示在ComboBox
。但是,设计器中的一切都很好。为了进一步测试,我添加了一个绑定到 SelectedPayee.Id
:
的 TextBox
<TextBox Grid.Row="7" Grid.Column="1" Text="{Binding Path=SelectedPayee.Id}" />
在设计时和运行时显示正确的数字,并且在我更改 ComboBox
中的 selection 时适当更新。唯一不能正常工作的是 ComboBox
在我导航到页面时没有正确显示 Payee
AccountName
。正如我所说,设计视图正确显示了我在设计器中的虚拟数据 ViewModel
。 ComboBox
有什么特别之处,我可能按错误的顺序做某事吗?
编辑 2:
我也使用
得到完全相同的结果
SelectedValue={Binding Path=SelectedPayee.Id, Mode=TwoWay}
绑定在 TextBox
中显示正确的 Payee.Id
取决于 Payee
在 ComboBox
中 selected,但它只是当我第一次导航到该页面时不显示 SelectedPayee
(但 TextBox
将填充正确的 Id
。)这对我来说真的很头疼....
编辑 3:
我把它弄清楚了。我遇到的最后一个问题是我在实际加载 ComboBox
之前设置了 SelectedPayee
,因此没有 属性 更改来触发 ComboBox
的 SelectedValue
] 改变。一旦我将对 LoadPayees()
的调用移到 SelectedValue
的分配上方,一切都像魅力一样。 请参阅下面的答案。
对于在寻找解决方案时偶然发现这个问题的任何人,我最终发现我正在设置 SelectedPayee
before 加载 ComboBox
.我将调用移到了 SelectedPayee
赋值上方的 LoadPayees()
,现在一切都按预期进行了!这是我的 OnNavigatedTo()
方法,供任何感兴趣的人使用:
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);
}
我在尝试在 WinRT 中绑定 ComboBox
时遇到问题。我正在使用 Prism/MVVM。我可以将 ItemsSource
绑定到 ObservableCollection
没问题,并且正在填充 ComboBox
。
我遇到的问题是,它会根据当前 Invoice
自动 select 适当的值。这是相关的 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
是我的 ObservableCollection
,CurrentInvoice
是 ViewModel
上的 属性,指向当前加载的 Invoice
项目。 Invoice
有一个名为 PayeeId
的 属性,您可能会猜到,它是 Payee
的 Id
,与此 Invoice
关联.
出于某种原因,无论我 select 是哪个 Invoice
,当我导航到我的页面时,ComboBox
都是空白的。空白,我的意思是没有任何 selected,但它填充了 Payees
集合。
如果我手动更改 selection,并保存我的 Invoice
,PayeeId
不会更改。我认为这可能与 SelectedValue
上的绑定有关,但到目前为止我一直无法弄清楚这一点。在此先感谢您的帮助!
以下是 Payees
和 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); }
}
编辑:
我在名为 SelectedPayee
的 ViewModel
上添加了一个 属性,它绑定到 ComboBox
的 SelectedItem
属性。这是更新后的定义:
<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" />
当我 select 一个 Payee
并保存时,它保存了新的 PayeeId
,但是当我加载页面时它仍然没有加载 SelectedPayee
显示在ComboBox
。但是,设计器中的一切都很好。为了进一步测试,我添加了一个绑定到 SelectedPayee.Id
:
TextBox
<TextBox Grid.Row="7" Grid.Column="1" Text="{Binding Path=SelectedPayee.Id}" />
在设计时和运行时显示正确的数字,并且在我更改 ComboBox
中的 selection 时适当更新。唯一不能正常工作的是 ComboBox
在我导航到页面时没有正确显示 Payee
AccountName
。正如我所说,设计视图正确显示了我在设计器中的虚拟数据 ViewModel
。 ComboBox
有什么特别之处,我可能按错误的顺序做某事吗?
编辑 2:
我也使用
得到完全相同的结果SelectedValue={Binding Path=SelectedPayee.Id, Mode=TwoWay}
绑定在 TextBox
中显示正确的 Payee.Id
取决于 Payee
在 ComboBox
中 selected,但它只是当我第一次导航到该页面时不显示 SelectedPayee
(但 TextBox
将填充正确的 Id
。)这对我来说真的很头疼....
编辑 3:
我把它弄清楚了。我遇到的最后一个问题是我在实际加载 ComboBox
之前设置了 SelectedPayee
,因此没有 属性 更改来触发 ComboBox
的 SelectedValue
] 改变。一旦我将对 LoadPayees()
的调用移到 SelectedValue
的分配上方,一切都像魅力一样。 请参阅下面的答案。
对于在寻找解决方案时偶然发现这个问题的任何人,我最终发现我正在设置 SelectedPayee
before 加载 ComboBox
.我将调用移到了 SelectedPayee
赋值上方的 LoadPayees()
,现在一切都按预期进行了!这是我的 OnNavigatedTo()
方法,供任何感兴趣的人使用:
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);
}