【问题标题】:How to set the selectedItem of a listpicker using databinding MVVM如何使用数据绑定 MVVM 设置列表选择器的 selectedItem
【发布时间】:2013-07-22 18:07:27
【问题描述】:

我的类别详细信息页面上有一个列表选择器

 <toolkit:ListPicker  HorizontalAlignment="Left"  Name="ListPickerCategoryTypes"
                               ItemsSource="{Binding CategoryTypes, Mode=TwoWay}" Header="Category Types;" 
                                 VerticalAlignment="Top" Width="438" Margin="9,6,0,0"  SelectedItem="{Binding CategoryTypeName, Mode=TwoWay}" >
                <toolkit:ListPicker.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding CategoryTypeName}"  Tag="{Binding Id}"></TextBlock>
                    </DataTemplate>

                </toolkit:ListPicker.ItemTemplate>


            </toolkit:ListPicker>

列表选择器填充正确,但是当我导航到详细信息页面时,从未设置 selectedItem?

我有一个类别名称文本框,可以正确显示所选类别名称,所以我知道它有数据只是不确定我做错了什么 与列表选择器。我想也许是因为我没有使用 CategoryTypeName 我试图使用我模型上的 Category Type ID。

我正在使用 MVVM,因此我希望能够在我的视图模型中执行此操作。

帮助的附加代码 SettingProduct 视图在列表框中列出了我拥有的所有产品。

<Grid x:Name="ContentPanel"
              Grid.Row="1"
              Margin="12,0,12,0">
            <ListBox x:Name="TileList" ItemTemplate="{StaticResource TileProductDataTemplate}" 
                         ItemsSource="{Binding DisplayProducts}" 
                         Margin="6,20,6,-8" 
                         SelectedItem="{Binding SelectedProduct, Mode=TwoWay}" >
                <Custom:Interaction.Triggers>
                    <i:EventTrigger EventName="Tap">
                        <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding EditDetailsPageCommand}" />
                    </i:EventTrigger>
                </Custom:Interaction.Triggers>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <toolkit:WrapPanel/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        </Grid>

点击产品,事件命令执行...

    this.EditDetailsPageCommand = new RelayCommand(this.GotoEditProductDetail, this.CanGotoEditProductDetail);

 public void GotoEditProductDetail()
        {


            //Messenger.Default.Send<NavigateToPageMessage>(new NavigateToPageMessage() { PageName = "SettingsProductDetail", SendObject = DisplayProducts });

           // Messenger.Default.Send<NavigateToPageMessage>(new NavigateToPageMessage(){PageName = "SettingsProductDetail", SendObject =  SelectedProduct});   
            Navigator.NavigateTo("SettingsProductDetail", SelectedProduct);
        }

它导航到 SettingsProductDetail 视图,并在构造函数中设置 DataContext 时在此行出错

SettingsProductDetail Xaml

<toolkit:ListPicker HorizontalAlignment="Left"  Name="ListPickerCategoryTypes"
                               ItemsSource="{Binding CategoryTypes}"
                               Header="Product Types;" 
                               VerticalAlignment="Top" Width="438" Margin="9,6,0,0" 
                               SelectedItem="{Binding SelectedCategoryType, Mode=TwoWay}"
                               >
                <toolkit:ListPicker.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding CategoryTypeName}" ></TextBlock>
                    </DataTemplate>

                </toolkit:ListPicker.ItemTemplate>


            </toolkit:ListPicker>
public SettingsProductDetail()
        {
            InitializeComponent();
            this.DataContext = new ViewModel.SettingsProductDetailViewModel(Navigator.Object);


        }

在我的 SettingsProductDetail 视图模型中 我有两个属性,一个用于 Itemsource,一个用于 selectedItem

public ObservableCollection<CategoryType> CategoryTypes
        {
            get { return _categoryType; }
            set
            {
                if (value != _categoryType)
                {
                    _categoryType = value;
                    base.RaisePropertyChanged("CategoryType");
                }
            }
        }

        public Model.CategoryType SelectedCategoryType
        {
            get { return _selectedCategoryType; }
            set
            {
                if (value != _selectedCategoryType)
                {
                    _selectedCategoryType = value;
                    base.RaisePropertyChanged("SelectedCategoryType");
                }
            }
        }

在构造中,我从产品视图传递的对象中填充 SelectedCategoryType。

 public SettingsProductDetailViewModel(object sendObject)
        {
            if (IsInDesignMode)
            {
                // Code runs in Blend --> create design time data.
            }
            else
            {
                ProductDetail = sendObject as DisplayProducts;

                if (ProductDetail == null)
                {
                    ProductDetail = new DisplayProducts();
                }
                else
                {
                    SelectedCategoryType = new CategoryType();
                    SelectedCategoryType.Id = ProductDetail.FkCategoryTypeID;
                    SelectedCategoryType.CategoryTypeName = ProductDetail.CategoryTypeName;
                }

                _TheStoreDataContext = new TheStoreDataContext(ConnectionString);
                PopulateHelperObjects();
                SettingsProductDetailSaveCommand = new RelayCommand<Model.Product>(param => SaveRecord(), param => (ProductDetail != null));
                SettingsProductDetailCancelCommand = new RelayCommand(CancelRecord, () => true);
            }
        }

【问题讨论】:

    标签: windows-phone-7 xaml data-binding mvvm


    【解决方案1】:

    您的 ViewModel 需要有一个名为 CategoryTypeSelected 的属性,该属性的类型为 T,其中 T 是您用来绑定 ItemsSource 的集合 CategoryTypes 中的对象类型。这样,CategoryTypeSelected 将始终是从列表中选择的项目。你像这样绑定它:

    <toolkit:ListPicker HorizontalAlignment="Left"  Name="ListPickerCategoryTypes"
                        ItemsSource="{Binding CategoryTypes, Mode=TwoWay}" ......
                        SelectedItem="{Binding CategoryTypeSelected, Mode=TwoWay}" >
    

    当然,你的 ViewModel 需要实现 INotifyPropertyChanged。

    【讨论】:

    • 我将不得不看看我是否可以这样做,我传递了一个类型为 productDetail 的对象,它基本上是从产品列表选择器中选择的产品。我猜测在传递对象之前,我还需要填充 Type 类别的 CategoryTypeSelected 以便它绑定到该对象。我可能做错了,因为我绑定到位于我的模型中的属性。我将不得不再次查看。
    • 我明白你在说什么。我修改了我的视图模型并添加了更改通知属性的属性,但我收到错误 SelectedItem must be set to a valid value。
    • 能否在您的问题中与我们分享更多代码? viewmodel 的重要部分和您要绑定的模型类...?
    • 好的,我得到的错误是 SelectedItem 必须始终设置为 SettingsProductDetail 视图上数据上下文设置的有效值。我将在主要问题中添加额外的代码,以便在评论中难以做到
    • 我明白了。我会修改我的问题。
    【解决方案2】:

    好的,我现在可以正常工作了...

    //It was my constructor and how I was setting the property. changed the constructor to this... if (ProductDetail == null)
                    {
                        ProductDetail = new DisplayProducts();
                    }
                    else
                    {
                        SelectedCategoryType = new CategoryType {CategoryTypeName = ProductDetail.CategoryTypeName};
                        //SelectedCategoryType.Id = ProductDetail.FkCategoryTypeID;
                    }
    

    // 然后将属性设置器更改为此...设置 {

                    if (_categoryType.Contains(value))
                    {
                        _selectedCategoryType = value;
                        base.RaisePropertyChanged("SelectedCategoryType");
                    }
                    else
                    {
                        _selectedCategoryType = _categoryType.FirstOrDefault((o) => o.CategoryTypeName == value.CategoryTypeName);
                        base.RaisePropertyChanged("SelectedCategoryType");
                    }
    
    
                    //if (value != _selectedCategoryType)
                    //{
                    //    _selectedCategoryType = value;
                    //    base.RaisePropertyChanged("SelectedCategoryType");
                    //}
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 2018-09-10
      • 2018-12-31
      相关资源
      最近更新 更多