【问题标题】:DataBinding a ComboBox's SelectedValue in WinRT Prism/MVVM在 WinRT Prism/MVVM 中对 ComboBox 的 SelectedValue 进行数据绑定
【发布时间】:2015-03-02 21:39:13
【问题描述】:

我在尝试在 WinRT 中绑定 ComboBox 时遇到问题。我正在使用棱镜/MVVM。我可以将ItemsSource 绑定到ObservableCollection 没问题,并且ComboBox 正在被填充。

我遇到的问题是让它根据当前的Invoice 自动选择适当的值。这是相关的 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 是我的ObservableCollectionCurrentInvoiceViewModel 上的一个属性,它指向当前加载的Invoice 项目。 Invoice 有一个名为 PayeeId 的属性,您可能会猜到,它是与此 Invoice 关联的 PayeeId

由于某种原因,无论我选择哪个Invoice,当我导航到我的页面时,ComboBox 都是空白的。空白是指没有选择任何内容,但它填充了 Payees 集合。

如果我手动更改选择并保存我的InvoicePayeeId 不会更改。我认为这可能与SelectedValue 上的绑定有关,但到目前为止我一直无法弄清楚这一点。提前感谢您的帮助!

以下是PayeesCurrentInvoice 的属性:

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); }
}

编辑:

我在ViewModel 上添加了一个名为SelectedPayee 的属性,该属性绑定到ComboBoxSelectedItem 属性。这是更新后的定义:

<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" />

当我选择Payee 并保存时,它会使用新的PayeeId 进行保存,但是当我加载页面时,它仍然无法使用ComboBox 中显示的SelectedPayee 加载。但是,设计师一切都很好。为了进一步测试,我添加了一个绑定到SelectedPayee.IdTextBox

<TextBox Grid.Row="7" Grid.Column="1" Text="{Binding Path=SelectedPayee.Id}" />

在设计时和运行时显示正确的数字,并且每当我更改ComboBox 中的选择时都会适当更新。唯一不能正常工作的是ComboBox 在我导航到页面时没有正确显示Payee AccountName。正如我所说,设计视图正确显示了我在设计师ViewModel 中拥有的虚拟数据。 ComboBox 是否有什么特别之处,我可能按错误的顺序做某事?

编辑 2:

我也得到了完全相同的结果使用

SelectedValue={Binding Path=SelectedPayee.Id, Mode=TwoWay}

绑定在TextBox 中显示正确的Payee.Id,这取决于在ComboBox 中选择了哪个Payee,但是当我第一次导航到页面时它只是不显示SelectedPayee(但是TextBox 将填充正确的 Id。)这对我来说真是令人头疼....

编辑 3:

我把一切都理顺了。我要解决的最后一个问题是我在实际加载ComboBox 之前设置了SelectedPayee,因此没有属性更改会触发ComboBoxSelectedValue 更改。一旦我将呼叫转移到LoadPayees() 上面的分配到SelectedValue,一切都像一个魅力。 请参阅下面的答案。

【问题讨论】:

  • 我不知道这个组件究竟是如何工作的,但通常组合框中的选择表示索引,而不是具体值。此外,如果您尝试将 selectedValue 硬编码到组合框中,它是否按预期工作?
  • ComboBox 上有 SelectedIndexSelectedValue 属性。 SelectedValue 应该是在 XAML 中显示的 PayeeId,而不是项目的索引。
  • 嗯,SelectedValue="{Binding Path=CurrentInvoice.PayeeId, Mode=TwoWay}"
  • 我会尝试删除 SelectedValue 和 SelectedValuePath 的使用,而是使用 SelectedItem。
  • @libik 我不确定最后一条评论“SelectedValue=...”是什么意思,这就是我已经说过的(暗示Path=)。这两种方法我都试过了,结果一样。

标签: c# mvvm combobox windows-runtime


【解决方案1】:

对于偶然发现这个问题并寻找解决方案的任何人,我最终发现我正在设置SelectedPayee 在加载ComboBox 之前。我将呼叫移至LoadPayees() 上方的SelectedPayee 分配,现在一切正常!这是我的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);
}

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2016-08-09
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    相关资源
    最近更新 更多