0
votes

I'm using a longlistselector and I want to get the text which is in the selected item on a Hold event. Unfortunately, Hold doesn't create a SelectedItem so I have to do a workaround. I've read quite a bit about this problem, but can't get a fully working solution. This is the error I get: Unable to cast object of typePhoneApp2.Favs to type 'System.String'.`. This error only appears when I hold in the open space next to the text in the items. How can I fix this?

Relevant C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.Xml;
using PhoneApp2.Resources;
using System.Xml.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Resources;

namespace PhoneApp2
{
    public class Favs
    {
        private string drank;

        public string Name
        {
            get { return drank; }
            set { drank = value; }
        }
        public Favs(string addition)
        {
            this.Name = addition;
        }
    }

    public partial class Favorites : PhoneApplicationPage
    {
        ObservableCollection<Favs> Favlist = new ObservableCollection<Favs>();
        Array list;
        Boolean alpha = false;
        public Favorites()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            //Populate LLL listBar
            listFavs.ItemsSource = Favlist;

            try
            {
                // copy the xml file to isolated storage
                using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (!file.FileExists("favorites.xml"))
                    {
                        StreamResourceInfo sr_en = Application.GetResourceStream(new Uri("Resources\\favorites.xml", UriKind.Relative));
                        using (BinaryReader br_en = new BinaryReader(sr_en.Stream))
                        {
                            byte[] data = br_en.ReadBytes((int)sr_en.Stream.Length);
                            //Write the file.
                            using (BinaryWriter bw = new BinaryWriter(file.CreateFile("favorites.xml")))
                            {
                                bw.Write(data);
                                bw.Close();
                            }
                        }
                    }
                    // work with file at isolatedstorage
                    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("favorites.xml", FileMode.Open, file))
                    {
                        XDocument xDoc = XDocument.Load(stream, LoadOptions.None);
                        list = xDoc.Descendants("cocktail").Select(n => n.Value).ToArray();
                        Array.Sort(list);
                        alpha = true;
                        foreach (string name in list)
                        {
                            Favlist.Add(new Favs(name));
                        }

                    }
                }
                Dispatcher.BeginInvoke(() =>
                {
                    pbLoading.IsIndeterminate = false;
                    pbLoading.Visibility = Visibility.Collapsed;
                });
            }
            catch (IOException IOExc)
            {
                MessageBox.Show(IOExc.Message);
            }
            catch (XmlException XmlExc)
            {
                MessageBox.Show(XmlExc.Message);
            }
            catch (Exception myExc)
            {
                MessageBox.Show(myExc.Message);
            }
        }

        private void listFavs_Hold(object sender, System.Windows.Input.GestureEventArgs e)
        {
            try
            {
                FrameworkElement element = (FrameworkElement)e.OriginalSource;
                String item = (String)element.DataContext;
                var booze = item.ToString();

                Dispatcher.BeginInvoke(() =>
                {
                    CustomMessageBox messageBox = new CustomMessageBox()
                    {
                        Caption = "Delete " + booze,
                        Message = "Are you sure you want to remove " + booze + " from your favorites? This cannot be made undone!",
                        LeftButtonContent = "Yes",
                        RightButtonContent = "No"
                    };
                    messageBox.Dismissed += (s1, e1) =>
                    {
                        switch (e1.Result)
                        {
                            case CustomMessageBoxResult.LeftButton:
                                using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
                                {
                                    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("favorites.xml", FileMode.Open, file))
                                    {
                                        XDocument xDoc = XDocument.Load(stream, LoadOptions.None);
                                        // delete node
                                        xDoc.Descendants("data").Elements("cocktail").Where(x => x.Value == booze).DescendantsAndSelf().Remove();
                                        xDoc.Save(stream);

                                        Favlist.Clear();

                                        list = xDoc.Descendants("cocktail").Select(n => n.Value).ToArray();
                                        Array.Sort(list);
                                        alpha = true;
                                        foreach (string name in list)
                                        {
                                            Favlist.Add(new Favs(name));
                                        }
                                    }
                                }
                                break;
                            case CustomMessageBoxResult.RightButton:
                                //do nothing
                                break;
                            case CustomMessageBoxResult.None:
                                //do nothing
                                break;
                            default:
                                break;
                        }
                    };

                    messageBox.Show();
                });
            }
            catch (InvalidCastException ICExc)
            {
                MessageBox.Show(ICExc.Message);
            }
            catch (IOException IOExc)
            {
                MessageBox.Show(IOExc.Message);
            }
            catch (XmlException XmlExc)
            {
                MessageBox.Show(XmlExc.Message);
            }
            catch (NullReferenceException NRExc)
            {
                MessageBox.Show(NRExc.Message);
            }
            catch (Exception myExc)
            {
                MessageBox.Show(myExc.Message);
            }
        }
    }
}

XAML:

<phone:PhoneApplicationPage
    x:Class="PhoneApp2.Favorites"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot">
        <Grid.Background>
            <ImageBrush Stretch="Fill" ImageSource="/Assets/AlignmentGrid.png"/>
        </Grid.Background>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid x:Name="Header" Grid.Row="0" Margin="12,17,0,616" Grid.RowSpan="2">
            <TextBlock Text="Cocktail" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0,242,46"/>
            <TextBlock Text="Favorites" Style="{StaticResource PhoneTextTitle1Style}" Margin="10,50,101,0" FontWeight="Bold"/>
            <Button x:Name="btnSettings" Content="" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="367,60,0,-50" Height="86" Width="91" Click="btnSettings_Click" BorderThickness="0">
                <Button.Foreground>
                    <ImageBrush Stretch="Fill"/>
                </Button.Foreground>
                <!--<Button.Background>
                    <ImageBrush Stretch="Fill" ImageSource="feature.settings.png"/>
                </Button.Background>-->
            </Button>
        </Grid>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,157,12,0">
            <phone:LongListSelector x:Name="listFavs" HorizontalAlignment="Left" Height="601" VerticalAlignment="Top" Width="456" Tap="listFavs_Tap" Hold="listFavs_Hold">
                <phone:LongListSelector.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}" FontSize="36" HorizontalContentAlignment="left"  HorizontalAlignment="Left" Height="82" Margin="0,-11,0,0" VerticalAlignment="Top" Width="456" Padding="0,0,0,0" BorderThickness="0">
                        </Button>
                    </DataTemplate>
                </phone:LongListSelector.ItemTemplate>
            </phone:LongListSelector>
            <ProgressBar x:Name="pbLoading" HorizontalAlignment="Left" Height="20" Margin="127,271,0,0" VerticalAlignment="Top" Width="200" IsIndeterminate="True"/>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>
2

2 Answers

3
votes

Probably in your case element.DataContext is your custom class Favs.

So you should do following casting:

private void listFavs_Hold(object sender, System.Windows.Input.GestureEventArgs e)
{
    try
    {
        FrameworkElement element = (FrameworkElement)e.OriginalSource;
        string item = null;

        if(element.DataContext is Favs)
        {
            Favs itemTmp = (Favs)element.DataContext;
            item = itemTmp.Name;
        }
        else
        {
            item = (string)element.DataContext;
        }       

        ....
0
votes

That is because you are catching many different FrameworkElements (TextBlock, Border and so on) and only TextBlock can be cast to string:

private void listFavs_Hold(object sender, System.Windows.Input.GestureEventArgs e)
{
    try
    {
        FrameworkElement element = (FrameworkElement)e.OriginalSource;
        if (element is TextBlock)
        {
            String item = (String)element.DataContext;
            var booze = item.ToString();
            // rest of code
        }
    }

This code will work only when user holds on Text. If user holds an empty space after the Text, then it is a Border which DataContext is Favs - you can perform suitable cast and take out your variable.