Xaml 数据绑定Listbox中ListPicker的DataContext问题

Xaml 数据绑定Listbox中ListPicker的DataContext问题,xaml,windows-phone-7,mvvm,binding,listpicker,Xaml,Windows Phone 7,Mvvm,Binding,Listpicker,我正在使用MVVM模式开发我的第一个WP7.1应用程序。这是我关于stackoverflow的第一个问题 在其中一个屏幕中,我通过添加信息按钮收集付款信息,如payment DescriptionTextbox、payment Mode/TypeToolkit:ListPicker、payment Due Date Toolkit:DatePicker等。这被包装在一个列表框中 <ListBox x:Name="AddPayListBox" ItemsSource="{Binding Ne

我正在使用MVVM模式开发我的第一个WP7.1应用程序。这是我关于stackoverflow的第一个问题

在其中一个屏幕中,我通过添加信息按钮收集付款信息,如payment DescriptionTextbox、payment Mode/TypeToolkit:ListPicker、payment Due Date Toolkit:DatePicker等。这被包装在一个列表框中

<ListBox x:Name="AddPayListBox" ItemsSource="{Binding NewPaymentsInfo}" SelectedItem="{Binding NewPayInfo}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBox x:Name="DescInput" Text="{Binding PayDesc, Mode=TwoWay}"/>
                    <toolkit:ListPicker x:Name="TypeInput" Header="Mode:" CacheMode="BitmapCache"
                            ItemsSource="{Binding DataContext.PayTypesList}"
                            SelectedItem="{Binding DataContext.SelectedPayTypesList, Mode=TwoWay}">
                        <toolkit:ListPicker.ItemTemplate>
                            <DataTemplate>
                                 <TextBlock Text="{Binding Path=PayTypesList.PayTypeDesc}"/>
                            </DataTemplate>
                        </toolkit:ListPicker.ItemTemplate>
                    </toolkit:ListPicker>
                    <toolkit:DatePicker x:Name="DateInput" Value="{Binding DueDate, Mode=TwoWay}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
        <Button x:Name="btnAddPay" Content="Add" Command="{Binding AddCommand}" />
    </StackPanel>
以下是ViewModel:不包括AddCommand,因为该部分工作正常

    public class PaymentViewModel
{
    public ObservableCollection<PaymentInfo> NewPaymentsInfo { get; set; }
    public PaymentInfo NewPayInfo;

    public ICommand AddCommand { get; set; }

    public ObservableCollection<SupportedPayTypes> PayTypesList;
    public SupportedPayTypes SelectedPayTypesList;

    public PaymentViewModel()
    {
        AddCommand = new DelegateCommand<PaymentSetup>(AddAction);

        PayTypesList = new ObservableCollection<SupportedPayTypes>();
        PayTypesList.Add(new SupportedPayTypes() { PayTypeIdx = 0, PayTypeDesc = "Cash" });
        PayTypesList.Add(new SupportedPayTypes() { PayTypeIdx = 1, PayTypeDesc = "Credit Card" });

        //SelectedPayTypesList = PayTypesList[0];
        SelectedPayTypesList = new SupportedPayTypes();
        SelectedPayTypesList.PayTypeIdx = PayTypesList[0].PayTypeIdx;
        SelectedPayTypesList.PayTypeDesc = PayTypesList[0].PayTypeDesc;

        NewPaymentsInfo = new ObservableCollection<PaymentInfo>();
        NewPayInfo = new PaymentInfo();
        NewPayInfo.PayDesc = "";
        NewPayInfo.PayType = SelectedPayTypesList.PayTypeIdx;
        NewPayInfo.DueDate = DateTime.Now;
        NewPaymentsInfo.Add(NewPayInfo);
    }
}
如果你发现什么东西不见了,请告诉我?我已经绞尽脑汁了:


谢谢大家!

是的,因此您正确地假设需要相对资源绑定才能访问PayTypesList集合。RelativeSource允许您在可视化树上漫游并绑定到任何父元素。在这种情况下,我建议您访问ListBox,然后使用其DataContext访问PaymentViewModel

帮自己一个忙并下载它,它将允许您在运行时查看应用程序的可视树,并帮助您为绑定选择适当的目标元素

ListPicker上的ItemsSource绑定变为:

ItemsSource="{Binding Path=DataContext.PayTypesList, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
这告诉绑定继续遍历可视化树,直到找到ListBox类型的第一个UIElement,然后将其用作绑定的目标。当然,您需要使用SelectedPayTypesList属性为SelectedItem创建类似的绑定


编辑:顺便说一下,我想您会希望SelectedPayType是PaymentInfo模型的成员,而不是PaymentViewModel。我假设您希望列表框中的每个项目都有自己的选择

欢迎来到SO!第一个问题很好。您是否正在ViewModel的构造函数中实例化NewPaymentsInfo?如果没有,则需要在实例化后对其发出属性更改通知。如果需要进一步查看,您可以发布模型/视图模型的代码:@ChrisO-谢谢!是的,我正在VM构造函数中实例化NewPaymentsInfo。我将很快发布Model/VM代码,并进一步尝试解释更多内容。我尝试了这一点,但得到了AncestorType not supported错误。在Silverlight和WP中似乎不支持它!看看啊,在这种情况下,这一个可能会有帮助,它似乎有一些变通办法。对不起,我帮不了什么忙,我用的是WPF,不是Silverlight。谢谢ChrisO给我的宝贵建议。我明天会查看你的链接并发布更新。我浏览了ChrisO提供的链接和子链接。我实现了提供的各种解决方案,但至少对于WP7来说,似乎没有一个是有效的。我回到原点,至少现在是这样:我认为标题场景很常见,但似乎WP7不支持它?!?
public partial class MainPage : PhoneApplicationPage
{
    private PaymentViewModel vm;

    public MainPage()
    {
        InitializeComponent();
        vm = new PaymentViewModel();
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        AddView.DataContext = vm;
        MainPivot.SelectedIndex = 1;
    }
}
ItemsSource="{Binding Path=DataContext.PayTypesList, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"