how to change MediaElement source when ListPicker_SelectionChanged? - c#

I'm trying to bind item from list picker to MediaElement Source when user I have the uri store in ListPickerItem Tag my problem I want to change the bleep.Source when ListPicker_SelectionChanged but my problem how to selected and cast it ?
private void ListPicker_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
// TODO: Add event handler implementation here.
bleep.Source = lp_sound.SelectedItem.ToString();
}
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<MediaElement x:Name="bleep" Source="soundFiles\ROAR.wav" AutoPlay="False" Visibility="Collapsed"/>
<Button x:Name="ButtonPlay" Content="play" HorizontalAlignment="Left" Margin="170,404,0,0" VerticalAlignment="Top" Click="ButtonPlay_Click"/>
<toolkit:ListPicker x:Name="lp_sound" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="408" SelectionChanged="ListPicker_SelectionChanged">
<toolkit:ListPickerItem x:Name="BestRoar" Content="Sound1" Tag="soundFiles\ROAR.wav" ></toolkit:ListPickerItem>
</toolkit:ListPicker>
</Grid>

You can do this to get results. I assumed that you have used local media file in your listpicker.
private void ListPicker_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e){
ListPickerItem item = lp_sound.SelectedItem as ListPickerItem;
if(item!=null)
bleep.Source = new Uri(Convert.ToString(item.Tag), UriKind.Relative);
}
Hope this will help.

Related

Get the parent ObservableCollection which Item selected - WP8

I'm writing an app to play streaming music, In app I have many list (Ranking list, Search Result List, Highlight song list .....), Each list have a same datatemplate which I bind to a LongListSelector for each Page. So I use this datatemplate as resources and put it in app.xaml
<DataTemplate x:Key="BasicVideoTemplate">
<Grid Tap="ChangeSong_Tap" RowsAuto="50,50" ColumnsAuto="150,*" Background="White" Margin="5,0,5,10">
<Grid.ColumnDefinition>
<ColumnDefinition Width = "150"/>
<ColumnDefinition Width = "*"/>
</Grid.ColumnDefinition>
<Grid.RowDefinition>
<RowDefinition Height = "50"/>
<RowDefinition Height = "50"/>
</Grid.RowDefinition>
<Border BorderThickness="1" BorderBrush="Black" Grid.RowSpan="2" Grid.Column="0" VerticalAlignment="Center" Margin="5,0,5,0">
<Image Source="{Binding Cover}"/>
</Border>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1" Style="{StaticResource BlackTextBlock}" Margin="5,0,0,0"/>
<TextBlock Text="{Binding Artist}" Grid.Row="1" Grid.Column="1" Foreground="Black" Margin="5,0,0,0"/>
<!-- .............. -->
</Grid>
</DataTemplate>
And this code (which i put in app.xaml.cs) to select a song from list, create a AudioTrack from this item and navigate to playSongPage:
private void ChangeSong_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var item = (SongItemModel)(sender as FrameworkElement).DataContext;
App.Model.ChangeSong(item.Id); /// this code will create a audio track for this item
(Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/Pages/DetailSongPage.xaml", UriKind.Relative));
}
Problem here is, I have to create a List< AudioTrack> for my playlist , So how can I get the parent list of clicked item and add it to the List< AudioTrack> , while all this code was put in app.xaml.cs ???
I would handle it in the SelectionChanged event of each longlistselector instead. The whole Tap thing on the grid doesn't sit well with me.
<phone:LongListSelector x:Name="myLSS" SelectionChanged="myLSS_SelectionChanged"/>
// event handler changes to
private void myLSS_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
LongListSelector lls = sender as LongListSelector; // get lls
var item = (SongItemModel) lls.SelectedItem;
App.Model.ChangeSong(item.Id); /// this code will create a audio track for this item
// now your ObservableCollection is just the ItemsSource, save a reference to it
// in the State manager so you can reference it on another page if you wish
ObservableCollection<SongItemModel> obs = (ObservableCollection<SongItemModel>) lls.ItemsSource;
PhoneApplicationService.Current.State["current_obs"] = obs;
// navigate..............
(Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/Pages/DetailSongPage.xaml", UriKind.Relative));
}

How to use (if possible) same source a tap event uses in a ContextMenu button click?

Im tweaking a Sound Player app to try and include a Save as Ringtone function. App uses Tiles and a Viewmodel. Tapping each tile plays a sound. I added a Context Menu to the Data Template to give the option on a Tap and Hold event to save that sound as a Ringtone. I am having some issues figuring out just how to use the same source as the Tiles use to play the sound. Below, first code is portion of the Mainpage.xaml. Then the c# code. What I have set at the bottom of the MainPage.cs for the _customRingtone Source is wrong. The emulator stops at "SoundData data = selector.SelectedItem as SoundData;" I cant figure out how to do the source in a similar way the Tile taps get the audio for playing it. I didnt post the ViewModel but can if you want me to. That is where the Tile Groups and sounds are loaded.
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="SoundTileDataTemplate">
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Click="Save_Click" Header="Save as Ringtone" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Grid Background="{StaticResource PhoneAccentBrush}"
Margin="0, 0, 12, 12">
<Grid VerticalAlignment="Top"
HorizontalAlignment="Right"
Width="40"
Height="40"
Margin="0, 6, 6, 0">
<Ellipse Stroke="{StaticResource PhoneForegroundBrush}"
StrokeThickness="3" />
<Image Source="/Assets/AppBar/Play.png" />
</Grid>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="{Binding Title}" Margin="6, 0, 0, 6" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<MediaElement
Name="AudioPlayer"
Volume="1" />
<!--Pivot Control-->
<phone:Pivot Title="{Binding Path=LocalizedResources.ApplicationTitle,
Source={StaticResource LocalizedStrings}}">
<phone:PivotItem Header="{Binding Animals.Title}">
<phone:LongListSelector x:Name="Animal"
SelectionChanged="LongListSelector_SelectionChanged"
Margin="0,0,-12,0"
ItemsSource="{Binding Animals.Items}"
LayoutMode="Grid"
GridCellSize="150,150"
ItemTemplate="{StaticResource SoundTileDataTemplate}"
/>
</phone:PivotItem>
public partial class MainPage : PhoneApplicationPage
{
private readonly SaveRingtoneTask
_CustomRingtone;
// Constructor
public MainPage()
{
InitializeComponent();
// Set the data context of the listbox control to the sample data
DataContext = App.ViewModel;
_CustomRingtone = new SaveRingtoneTask();
_CustomRingtone.Completed +=
customeRingtone_Completed;
BuildLocalizedApplicationBar();
}
// Load data for the ViewModel Items
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
}
private void LongListSelector_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
LongListSelector selector = sender as LongListSelector;
// verifying our sender is actually a LongListSelector
if (selector == null)
return;
SoundData data = selector.SelectedItem as SoundData;
// verifying our sender is actually SoundData
if (data == null)
return;
private void customeRingtone_Completed(object sender, TaskEventArgs e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show(#"Saved");
}
else if (e.TaskResult == TaskResult.Cancel)
{
MessageBox.Show(#"Canceled");
}
else
{
MessageBox.Show(#"Not Saved");
}
}
private void Save_Click(object sender, System.Windows.RoutedEventArgs e)
{
LongListSelector selector = sender as LongListSelector;
SoundData data = selector.SelectedItem as SoundData;
**_CustomRingtone.Source = new Uri(data.FilePath, UriKind.RelativeOrAbsolute**);
_CustomRingtone.DisplayName = "Ring";
_CustomRingtone.Show();
}
You Save_Click event handler is not passed a LLS, but a context MenuItem. The DataContext of the MenuItem is the object you are after.
private void Save_Click(object sender, System.Windows.RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
SoundData data = element.DataContext as SoundData;
_CustomRingtone.Source = new Uri(data.FilePath, UriKind.RelativeOrAbsolute**);
_CustomRingtone.DisplayName = "Ring";
_CustomRingtone.Show();
}

Tap and hold Listbox Windows Phone

Does anybody know how can I add event whenever I press my listbox it will directly run my code. I need it to change my listbox selected item. This is my xaml:
<ListBox x:Name="ListNabi" SelectionChanged="ListNabi_SelectionChanged" ItemsSource="{Binding}" Tap="ListNabi_Tap" Hold="ListNabi_Hold">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,0,5,0">
<!--<Image Source="{Binding ImageSource}" Stretch="None"/>-->
<Grid Width="480" Background="White">
<Image x:Name="listDaun" Source="/Images/Button/Button List.png"
Margin="0,5,5,5" Width="38" HorizontalAlignment="Left"></Image>
<TextBlock x:Name="namaNabi" TextWrapping="NoWrap"
Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="36" Foreground="#00ADCE" Margin="40,5,0,5"></TextBlock>
<Rectangle Margin="0,50,0,0" Height="2" Fill="#00ADCE" Width="480"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in CS I did like this:
private void ListNabi_Hold(object sender, System.Windows.Input.GestureEventArgs e)
{
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
}
MessageBox.Show("tes");
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
NavigationService.Navigate(new Uri("/Pages/25_Nabi/DetailPage.xaml?id="
+ ListNabi.SelectedIndex, UriKind.Relative));
ListNabi.SelectedIndex = -1;
}
}
But it will only run my code (in this context changeColor()) whenever I hold my listbox after some time or after I release my finger. Is there any event I can use to start run my code whenever my finger start touch?
For that use the following events: ManipulationStarted, ManipulationDelta and ManipulationCompleted. You will get everything you need from positions to the number of different touch points.
You can do sophisticated things with it like dragging and pinching.

Unable to handle MouseDown event from ListView Item (Label)

I have a List View which I am populating with Labels via code. When the user clicks the label I want to handle the MouseDown event, but it doesn't fire. The preview mouse down does fire.
I understand there is something here about routing / bubbling events which I guess is going to the issue I'm hitting, this is a concept I'm yet to grasp.
I cannot use the preview event as this does not contain the object I need (the label information does not get assigned until the second click of the label, so I assume I need the MouseDown and not the preview)
Appreciate your time.
XAML
<telerik:RadTabItem x:Name="Media" Header="Media" Height="22" Width="100">
<Grid x:Name="ListboxMedia">
<ListView x:Name="ListViewImages" HorizontalAlignment="Left" Height="303" Margin="697,10,0,0" VerticalAlignment="Top" Width="178" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" IsTabStop="True" TabIndex="3" MouseDown="ListViewImages_MouseDown" PreviewMouseDown="ListViewImages_PreviewMouseDown">
<ListView.View>
<GridView>
<GridViewColumn x:Name="ListViewImageColumn" Header="Images" Width="178" />
</GridView>
</ListView.View>
</ListView>
<Button x:Name="BtnUpload" Content="Upload" Height="24" Margin="809,318,38,0" VerticalAlignment="Top" Click="BtnUpload_Click"/>
<Button x:Name="BtnDownload" Content="Download" Height="24" Margin="728,318,109,0" VerticalAlignment="Top"/>
<Image x:Name="ImageViewPort" HorizontalAlignment="Left" Height="293" Margin="21,20,0,0" VerticalAlignment="Top" Width="581"/>
</Grid>
</telerik:RadTabItem>
Method which populates Labels into ListViewImages
void PopulateMedia()
{
var collectImages = new Media().CollectMediaForAsset(_assetId);
int i = 1;
foreach (var collectImage in collectImages)
{
var label = new Label();
label.Tag = collectImage.FileName;
label.Content = "Image" + i.ToString();
ListViewImages.Items.Add(label);
i++;
}
}
Handlers
private void ListViewImages_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Debug.WriteLine("Clicked Down"); //does not work
}
private void ListViewImages_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Debug.WriteLine("Clicked Preview"); //works
}
Used selection changed event instead

No more displayed image on ListBox everytime I select an item

PROBLEM:
I got the answer when doing some binding from ListBoxSource to ListBoxDisplay BUT weird thing happened:
The selecting and deselecting of items are working fine and displays exactly the selected items on the other ListBox named "ListBoxDetails BUT everytime I select an item the image is gone but selection highlights remain but has no more image in it. (You can still deselect it though even if no more image because the screenspace is still there)
NOTE: I have no other control inside the ListBoxSource (SelectionMode=Multiple) ONLY Image
CODE XAML:
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<WrapPanel Height="149" Orientation="Horizontal" Width="193">
<Image HorizontalAlignment="Left" Height="128" Width="180" Margin="0"/>
</WrapPanel>
</DataTemplate>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate2">
<UniformGrid x:Name="UniformGridImageList"/>
</ItemsPanelTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListBox x:Name="ListBoxSource" Width="450" Margin="9,3,442,178" ItemsPanel="{DynamicResource ItemsPanelTemplate2}" SelectionMode="Multiple" d:LayoutOverrides="GridBox" HorizontalAlignment="Left" />
<ListBox Name="ListBoxDisplay" Height="659" HorizontalAlignment="Right" Margin="460,5,0,0" VerticalAlignment="Top" Width="382" ItemsSource="{Binding ElementName=ListBoxSource, Path=SelectedItems}" />
<Button x:Name="buttonLoadImages" Content="Button" HorizontalAlignment="Left" Height="51" Margin="33,0,0,70" VerticalAlignment="Bottom" Width="183" Style="{DynamicResource ButtonStyle1}" Click="buttonLoadImages_Click"/>
<Button Content="Clear" Height="55" HorizontalAlignment="Right" Margin="0,717,442,0" Name="buttonClearListBox" VerticalAlignment="Top" Width="177" Click="button1_Click" />
</Grid>
CODE C#:
above declaration:
private List<Image> _imageList = new List<Image>();
.
.
.
private void buttonLoadImages_Click(object sender, System.Windows.RoutedEventArgs e)
{
this._imageList = GetImageList(#"C:\Users\Public\Pictures\Sample Pictures");
foreach (Image curImage in this._imageList)
{
ListBoxSource.Items.Add(curImage);
}
}
#region GetImageList Method
private List<Image> GetImageList(string strPath)
{
List<Image> imageList = new List<Image>();
string strFilePath = "";
if (Directory.Exists(strPath) == false)
{
MessageBox.Show(string.Format("{0} path could not be found.", strPath));
return imageList;
}
try
{
DirectoryInfo dirInfo = new DirectoryInfo(strPath);
FileInfo[] files = dirInfo.GetFiles("*.jpg",SearchOption.AllDirectories);
foreach (FileInfo curFile in files)
{
strFilePath = curFile.FullName;
Image curImage = new Image();
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = new Uri(curFile.FullName, UriKind.Absolute);
bmpImage.EndInit();
curImage.Height = 140;
curImage.Stretch = Stretch.Fill;
curImage.Source = bmpImage;
curImage.Margin = new Thickness(10);
imageList.Add(curImage);
}
if (imageList.Count == 0)
MessageBox.Show(string.Format("No image files could be found in {0}", strPath));
}
catch (Exception ex)
{
MessageBox.Show(string.Format("{0}-{1}", ex.Message, strFilePath));
}
return imageList;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.listBoxSource.Items.Clear();
}
You are creating Image UI objects and adding them directly to your ListBox.
This means that the SelectedItems is an Image UI object, so ListBox #2 is trying to set it's Items to the exact same Image object reference. This isn't allowed in WPF because UI objects can only have a single parent, however because it is a Binding error, WPF is silent about it (except for probably a warning)
I would recommend making your List<Image> into a List<string> which contains the path name for the image, and changing your <Image> in the template to use that string as it's Source. Also, don't forget to set the ItemTemplate on both your ListBoxes.
<DataTemplate x:Key="ItemTemplate">
<WrapPanel Height="149" Orientation="Horizontal" Width="193">
<Image Source="{Binding }" HorizontalAlignment="Left" Height="128" Width="180" Margin="0" />
</WrapPanel>
</DataTemplate>
I did a quick test and it works fine once you fill your ListBoxes with Strings instead of UI objects

Categories

Resources