Search Items in The ListBox In Windows Phone 7 - c#

I want to search the name in the list box. I am using MVVM pattern in my application.
My Xaml coding for Listbox
<ListBox Height="440" Background="Azure" ItemsSource="{Binding Content,Mode=TwoWay}" HorizontalAlignment="Left" Margin="0,230,0,0" Name="OutGoingInvitationList" VerticalAlignment="Top" Width="468" BorderBrush="#00565353" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="ListPersonImage" Source="{Binding ListImage}" Height="100" Width="100" Stretch="Uniform" Margin="10,2,0,0" ImageFailed="Image_ImageFailed" />
<TextBlock Text="{Binding ListFullName}" Name="ListPersonFullName" Width="200" Foreground="Black" Margin="10,10,0,0" FontWeight="SemiBold" FontSize="22" />
<TextBlock Text="{Binding ListBio}" Name="ListPersonBio" FlowDirection="LeftToRight" Foreground="Black" Margin="-200,50,0,0" FontWeight="ExtraLight" FontSize="20" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here Content have all the list values.
Now it shows the result. Now i want search the person name. I want to write the code in
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
}
Is it possible to search the names in the listbox. Here i want only show the items in Listbox searched items only. Sorry for the poor English.
Please tell me how to perform this action.
Thanks in advance..
My View Model:
invitationsButton = new ReactiveAsyncCommand();
var invitationResults = invitationsButton.RegisterAsyncObservable(_ =>
{
return HTTPServices.postAndGetResponse((new PersonSearchOperation().GetInvitations(ServiceConstants.Identity_Number)));
});
invitationResults.Subscribe(
x =>
{
ServiceModel sm = new ServiceModel();
Content = new List<ListContactsModel>();
Content1 = new List<ListContactsModel>();
ServiceConstants.Temp_Response = x;
List<ListContactsModel> result = ListContactsModel.extract(x, sm, OutGoingInvitation);
if (!((string.IsNullOrEmpty(sm.NetErrorCode)) && (string.IsNullOrEmpty(sm.ProvResErrCode))))
{
string errCode = !string.IsNullOrEmpty(sm.NetErrorCode) ? sm.NetErrorCode : sm.ProvResErrCode;
string errDesc = !string.IsNullOrEmpty(sm.NetErrorDesc) ? sm.NetErrorDesc : sm.ProvResErrDesc;
MessageBox.Show(errCode + "/" + errDesc);
}
else if (result.Count > 0)
{
Content.AddRange(result);//Outgoing Invitations
}
else
{
MessageBox.Show("There is No Invitations For You"); //Use Resource Bundle
}
}
);
Now Content have all the result.
Please tell me now where i have to implement Search operation?
Actually i have no idea where i have to write the Search Operation Code??
In My view Model I have add this code. I can see the output in Console Window. But UI is not updating.
public void SearchMethod(String searchValue)
{
Console.WriteLine("searchValue...." + searchValue);
Console.WriteLine("ServiceConstants.Temp_Response ...." + ServiceConstants.Temp_Response);
AppGlobalConstants.Temp_SearchValue = searchValue;
ServiceModel sm = new ServiceModel();
Content = new List<ListContactsModel>();
List<ListContactsModel> result = ListContactsModel.extract(ServiceConstants.Temp_Response, sm, OutGoingInvitation);
if (!((string.IsNullOrEmpty(sm.NetErrorCode)) && (string.IsNullOrEmpty(sm.ProvResErrCode))))
{
string errCode = !string.IsNullOrEmpty(sm.NetErrorCode) ? sm.NetErrorCode : sm.ProvResErrCode;
string errDesc = !string.IsNullOrEmpty(sm.NetErrorDesc) ? sm.NetErrorDesc : sm.ProvResErrDesc;
MessageBox.Show(errCode + "/" + errDesc);
}
else if (result.Count > 0)
{
Content.AddRange(result);
Console.WriteLine("Content.Count==>>" + Content.Count);
}
}
In My CS file
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
listContactsViewModel.SearchMethod(userIDTextBox.Text);
}
Sorry. I am very new to windows phone application development. In fact this is my very first project. That's why i don't have any idea. Please tell me where i have to make changes??

In your ViewModel you should have a private collection to hold the orignal list while you can set the search result in content.
In your viewmodel
private List<YourClass> orignalList;
public void Search(string query)
{
// do your query
List<YourClass> list = get...;
// clear content
Content.Clear();
foreach(var item in list)
{
Content.Add(item)
}
}
If you clear the query, you use the orignalList to fill Content.
Remember to set Content as ObservableCollection

Related

cascading dropdown in wp8

I'm try to create cascading dropdown when i select first one it's working fine.On SelectionChanged i'm try to bind second drop down on code behind it's show the result fine.But Dropdown show empty.here is my code..
Location ld = new Location();
ld = categoryList.SelectedItem as Location;
string id = "0";
try
{
id = Convert.ToString(ld.id);
}
catch (Exception ex)
{ }
if (id != "0")
{
// lstSublocation.Visibility = Visibility.Visible;
var lst = _lstlocation.Where(z => z.id == id).Select(z => z.sub_location).ToList();
lstSublocation.ItemsSource = lst;
}
In lst show 2 items.
<toolkit:ListPicker x:Name="lstSublocation" Foreground="Black"
BorderThickness="2" SelectionMode="Single"
VerticalAlignment="Bottom" Margin="12,0,10,460" BorderBrush="LightGray" Height="68" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" Margin="12 0 0 0" Foreground="Black"/>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0 21 0 20">
<TextBlock Text="{Binding name}"
Foreground="Black"
/>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
Here is front end code ..... :( 2 hours struggle with this code like wrestlemania fight... :)
Code should work (as posted), this is probably where the problem is
var lst = _lstlocation.Where(z => z.id == id).Select(z => z.sub_location).ToList();
lstSublocation.ItemsSource = lst;
Put a break point at lstSublocation.ItemsSource = lst; and check what lst is
Make sure it's actually a List<your_model> and that your_model has a Property of name not just a public variable.. like this
public class sample_model
{
public sample_model()
{
this.name = "default";
}
public string name { get; set; } // this is bindable
// public string name; // this is NOT bindable
}

How do I access a TextBlock which is inside my ListBox's DataTemplate (but not Binding) in XAML?

XAML
<ListBox x:Name="lsbQueue" Margin="0,0,0,10" Grid.RowSpan="2" Loaded="lsbQueue_Loaded" SelectionChanged="lsbQueue_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stk" Orientation="Vertical">
<!-- This is the bugger which I need to access behind the scenes-->
<TextBlock x:Name="tbActive" FontSize="35" FontFamily="Segoe UI Symbol" Text="" Height="115" Margin="0,0,0,-110" Tag="Active"/>
<!-- -->
<TextBlock Text="{Binding Path=SongName}" FontSize="35" Width="388" FontWeight="Normal" Margin="60,0,0,0"/>
<TextBlock Width="390" FontWeight="Thin" Margin="60,-5,0,10" Opacity="0.55">
<Run Text="{Binding Artist}" />
<Run Text=", " /> <!-- space -->
<Run Text="{Binding Album}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The above is my Listbox which is the populated from code behind with the help of this:
C#
void GetQueue()
{
var songs = new List<song>();
for (int i = 0; i < MediaPlayer.Queue.Count; i++)
{
songs.Add(new song {
SongName = MediaPlayer.Queue[i].Name.ToString(),
Album = MediaPlayer.Queue[i].Album.Name.ToString(),
Artist = MediaPlayer.Queue[i].Artist.ToString()
});
}
lsbQueue.ItemsSource = songs.ToList();
//lsbQueue.SelectedValue.ToString();
GlobalVars._song = MediaPlayer.Queue.ActiveSongIndex;
lsbQueue.SelectedIndex = GlobalVars._song;
// .......
}
and
public class song
{
public string SongName { get; set; }
public string Album { get; set; }
public string Artist { get; set; }
}
public class Song : List<song>
{
public Song()
{
Add(new song {
SongName = "",
Album = "",
Artist = ""
});
}
}
I have tried using VisualTreeHelper and other extension methods which can be found here:
GeekChamp
Falafel Blog
But I've had no success. I've almost given up on this. Does anyone have any ideas what can be done. Thank you.
As you can see - I can successfully get the Media Queue but I would like to show a visual hint on the left hand side of the "SelectedItem" like the playing character in the TextBlock - tbActive. Hope this helps!
Since the <TextBlock> is the first entry in the DataTemplate that you're trying to access use the provided function from the GeekChamp's tutorial.
<ListBox x:Name="lb" SelectionChanged="lb_SelectionChanged"/>
// namespaces
using System.Windows.Media;
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
private void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// get the ListBoxItem by SelectedIndex OR index number
//ListBoxItem lbi = (ListBoxItem) this.lb.ItemContainerGenerator.ContainerFromIndex(lb.SelectedIndex);
// get the ListBoxItem by SelectedItem or object in your ViewModel
ListBoxItem lbi = (ListBoxItem)this.lb.ItemContainerGenerator.ContainerFromItem(lb.SelectedItem);
// get your textbox that you want
TextBlock tbActive= FindFirstElementInVisualTree<TextBlock>(lbi);
}
The above answer will throw an Exception - just like Chubosaurus Software suggested the SelectedItem will be a 'Song' and thefore the TextBlock will also be a null. And it won't work.
You can try get StackPanel from ListBox's Selected Item using as operator and then use Children property with indexer to get to your TextBlock.
StackPanel temp = lsbQueue.SelectedItem as StackPanel;
var textBlock = temp.Children[0] as TextBlock;
What exactly do you want to accomplish? Maybe another Binding + possible ValueConverter would be way better solution...

How I display phone's mp3 files list in one window in windows phone 8

I want to make music player in windows phone 8 using code behind language c# and design in XAML. I want to display mp3 file list of phone in one window.
How I display phone's mp3 files list in one window ?
Well, if you want to make a list of your the songs that are present inside the phones media library then
make a base class SongModel
public class SongModel
{
public int songId { get; set; }
public string songName { get; set; }
}
Make global variables
MediaLibrary mLibrary = new MediaLibrary();
SongCollection songs;
List<SongModel> songnames;
now in the pages constructor write these lines of code
songs = mLibrary.Songs;
MediaPlayer.ActiveSongChanged += MediaPlayer_ActiveSongChanged;
MediaPlayer.MediaStateChanged += MediaPlayer_MediaStateChanged;
if (songs.Count != 0)
{
songnames = new List<SongModel>();
for (int i = 0; i < songs.Count; i++)
{
songnames.Add(new SongModel() { songName = songs[i].Name, songId = i });
}
lbMusic.ItemsSource = songnames; // lbMusic is the list/listbox here
}
xaml for listbox lbMusic
<ListBox SelectionChanged="lbMusic_SelectionChanged" Foreground="Black" FontWeight="Bold" Name="lbMusic" Height="210" Width="480" Margin="0,10,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,5,0,5" Width="480" Background="White" Height="40">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding songName}" TextTrimming="WordEllipsis" Margin="30,0,0,0" Tag="{Binding songId}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
To play a song based on its song ID, Ovveride the selectionChanged event of the listbox.
private void lbMusic_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
if (lbMusic.SelectedIndex != -1)
{
int musicId = (lbMusic.SelectedItem as SongModel).songId;
MediaPlayer.Play(songs, musicId);
}
}
catch
{
MessageBox.Show(TextResources.resErrorActiveSong);
}
}
I hope this helps as expected

WP7 Select ObservableCollection Item using parameter passed from previous page

I have two table. Table 1 from a online service which forms the Listbox on my original Page. The second table is located in an internal DB and contains a uniqie field with the same values as a field in table1.
I want to use a listbox in table 1 to load details from table2 in a seperate page.
The code below is my code from my second page however it keeps throwing an exception "Items Collection must be empty before using ItemSource"
Can someone correct this code or sugest better way to do this?
public partial class PlayerProfilePanoramaPage : PhoneApplicationPage
{
object _SelectedPlayer;
string _playerName;
public CollectionViewSource viewsource { get; set; }
public PlayerProfilePanoramaPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(PhoneApplicationPage_Loaded);
LoadPlayerProfile();
LoadPlayerDetails();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = _SelectedPlayer;
}
private void LoadPlayerProfile()
{
FrameworkElement root2 = Application.Current.RootVisual as FrameworkElement;
var currentplayer = root2.DataContext as Mens_Leaders;
_SelectedPlayer = currentplayer;
_playerName = currentplayer.Name;
}
private void LoadPlayerDetails()
{
ObservableCollection<PlayerProfileTable> playerProfile = new ObservableCollection<PlayerProfileTable>();
viewsource = new CollectionViewSource();
viewsource.Filter += PlayerProfile_Filter;
viewsource.Source = playerProfile;
this.PlayerPanorama.ItemsSource = viewsource.View;
}
void PlayerProfile_Filter(object sender, FilterEventArgs e)
{
if (e.Item != null)
e.Accepted = ((PlayerProfile)e.Item).Name.Equals(_playerName);
}
}
edit: Xaml is currently only simple to text that binding was working. Datacontexts and source bindings not defined in Xaml as defined in code. Xaml code provided below.
<controls:Panorama Name="PlayerPanorama" Title="my application">
<!--Panorama item one-->
<controls:PanoramaItem Name="panoramaPage1" Header="item1">
<Grid Name="Grid1">
<StackPanel>
<TextBlock Height="30" Name="textBlock1" Text="{Binding PlayerName, FallbackValue=Name}" />
<TextBlock Height="30" Name="textBlock2" Text="{Binding Height, FallbackValue=Height}" />
<ScrollViewer Height="387" Name="scrollViewer1" Width="422">
<TextBlock Height="auto" Name="textBlock3" Text="{Binding ProfileBlurb, FallbackValue=Blurb}" />
</ScrollViewer>
</StackPanel>
</Grid>
</controls:PanoramaItem>

Databinding with a listbox

I have a bit of code that reads a json response from an HTTP server, it then parses this and inserts the data into a ListBox control.
The event I fire off when the download is complete is the following:
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer ser = null;
try
{
ser =
new DataContractJsonSerializer(typeof(ObservableCollection<UserLeaderboards>));
ObservableCollection<UserLeaderboards> users =
ser.ReadObject(e.Result) as ObservableCollection<UserLeaderboards>;
foreach (UserLeaderboards em in users)
{
int Fid = em.id;
string Fusername = em.username;
int Fscore = em.score;
lstbLeaders.Items.Add(Fid + Fusername + Fscore);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Now, when I do the items.add I presume it's just joining up the 3 variables and adding it to one column in the ListBox. This works fine and I see all 3 items joined up and displayed.
I want to separate this and make it look a bit nicer so I've created some XAML to try and bind the variables to textblocks. The following is just binding the username. I also have a public class that get/sets all 3 variables.
<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0"
Name="lstbLeaders" VerticalAlignment="Top" Width="446">
<DataTemplate>
<TextBlock Text="{Binding Source=Fusername}" />
</DataTemplate>
</ListBox>
When running the above I get nothing displayed at all. I have a feeling it's something simple?
Thanks.
To display a simple string your xaml should look like this:
<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0"
Name="lstbLeaders" VerticalAlignment="Top" Width="446">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
and you have to provide an object instead of a simple string if you want to split the properties to make it look nicer. If you just add Fid + Fusername + Fscore you will end up with a plain string.
<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0"
Name="lstbLeaders" VerticalAlignment="Top" Width="446">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Score}" />
</StackPanel>
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
You will need a view class:
public class UserView
{
public string Id {get;set;}
public string Name {get;set;}
public int Score {get;set;}
}
in your code behind:
var usersList = new List<UserView>();
foreach (UserLeaderboards em in users)
{
int Fid = em.id;
string Fusername = em.username;
int Fscore = em.score;
usersList.Add(new UserView { Id = Fid, Name = Fusername, Score = Fscore} );
}
lstbLeaders.ItemsSource = usersList;
Further notes:
Why not bind the ObservableCollection<UserLeaderboards> direcectly to the list box?
If there is no reason to convert to an other type skip the foreach part of the code and simply set lstbLeaders.ItemsSource = users;.
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
var ser = new DataContractJsonSerializer(
typeof(ObservableCollection<UserLeaderboards>));
var users = ser.ReadObject(e.Result)
as ObservableCollection<UserLeaderboards>;
lstbLeaders.ItemsSource = users;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Take look at the MVVM pattern. If you want to work with XAML you should know about this. It simplifies your work and creates cleaner code.
If you want to add edit functionality or data can change you may need to implement INotifyPropertyChanged on the View class.
You can use type inference which especially helps when working with cumbersome class names. var list = new ObservableCollection<SomeLongTypeName>() saves much typing and screen estate.
Hungarian notation makes me cringe ;)
I think you missed the ItemTemplate.
Try this
<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" Name="lstbLeaders" VerticalAlignment="Top" Width="446">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Source=Fusername}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Categories

Resources