0
votes

I have a listpicker on my Category details page

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

The list picker populates correctly but when I navigate to the details page the selectedItem is never set?

I have a category Name textbox that is correctly displaying the category name that was selected so I know it has the data just not sure what I am doing wrong with the listpicker. I thought maybe it was that I wasnt using the CategoryTypeName I was trying to use the Category Type ID that is on my model.

I am using MVVM so I would like to be able to do this in my view model.

Addtional Code to help The SettingProduct view lists all the products I have in a listbox.

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

on the tap of a product the event command executes...

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

It navigates to teh SettingsProductDetail View and in the constructor it errors on this line when setting the 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);


        }

In my viewmodel for the SettingsProductDetail I have two properties one for teh Itemsource and one for the 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");
                }
            }
        }

In the construct is where I am populating the SelectedCategoryType from the object passed from the product view.

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

2 Answers

4
votes

Your ViewModel needs to have a property called CategoryTypeSelected which will be of the type T, where T is the type of objects that are in the collection CategoryTypes which you used to bind your ItemsSource. This way, the CategoryTypeSelected will always be the item selected from the list. You bind it like this:

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

Of course, your ViewModel needs to implement INotifyPropertyChanged.

0
votes

Ok I now have it working...

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

// and then changed the property setter to this... set {

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