Read MP3 Tag attribute in Silverlight - silverlight

I know it works to read out the MP3 Tag attribute MP3V1 in silverlight. I know it works without any third party moduls. But when I use the MP3 workflow like Microsoft described I always get the count of zero attributes in my MP3 file.
How to solve?
Example project:
Download MP3 demo file from here:
http://www.file-upload.net/download-2617219/Elenor_techno.mp3.html
<UserControl x:Class="MP3_Tag_test.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White" Margin="12">
<StackPanel Orientation="Vertical">
<MediaElement x:Name="MediaHelper" Visibility="Visible" />
<TextBlock x:Name="txtTitle" Text="Title" FontSize="28" />
<Button Content="STOP" Height="23" HorizontalAlignment="Left" Name="Button3" Width="75" />
<Button Content="Play MP3" Height="23" HorizontalAlignment="Left" Name="Button1" VerticalAlignment="Top" Width="75" Margin="0,20,0,0" />
<Button Content="Play stream" Height="23" HorizontalAlignment="Left" Name="Button2" VerticalAlignment="Top" Width="75" />
</StackPanel>
</Grid>
Partial Public Class MainPage
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
End Sub
Private Sub MediaHelper_CurrentStateChanged(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MediaHelper.CurrentStateChanged
If Me.MediaHelper.Attributes.ContainsKey("Title") Then Me.txtTitle.Text = Me.MediaHelper.Attributes("Title")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Me.txtTitle.Text = "Loading mp3..."
Me.MediaHelper.Source = New Uri("http://dave-d.ch/database/music/public/1000036869_stefan%20lange%20koolja.mp3")
Me.MediaHelper.Play()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click
Me.txtTitle.Text = "Loading stream..."
Me.MediaHelper.Source = New Uri("http://asx.skypro.ch/radio/internet-128/fm1-nord.asx")
Me.MediaHelper.Play()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button3.Click
Me.MediaHelper.Stop()
End Sub
End Class

Ok. I created my own class and now I am submitting the MP3 Tag via service to Silverlight page. But I am still interested by Silverlight Tag reader does not work.

Related

MVVM Bindings doesnt update with PropertyChanged

All my bindings are not updated and I don't understand why
My Model is:
Public Class TestModel
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyProperyChange(ByVal Info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Info))
End Sub
Private m_vorname As String
Public Property vorname() As String
Get
Return m_vorname
End Get
Set(ByVal value As String)
If m_vorname <> value Then
m_vorname = value
NotifyProperyChange("vorname")
MessageBox.Show("Vorname wurde zu:" + m_vorname)
End If
End Set
End Property
Public Sub wertverandern()
vorname = "Lukas"
End Sub
End Class
My View is the MainView with this settings:
Imports System.ComponentModel
Class MainWindow
Private WithEvents m_Person As New TestModel
Public Sub New()
' Dieser Aufruf ist für den Designer erforderlich.
InitializeComponent()
Me.DataContext = New TestModel()
' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
End Sub
Private Sub btn_Test_Click(sender As Object, e As RoutedEventArgs) Handles btn_Test.Click
m_Person.vorname = "MOINSEN"
End Sub
Private Sub m_Person_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Handles m_Person.PropertyChanged
MessageBox.Show("Ausgeloest:" + m_Person.vorname, e.PropertyName)
End Sub
Private Sub gelicked(sender As Object, e As RoutedEventArgs) Handles btn_XXX.Click
m_Person.wertverandern()
End Sub
End Class
My XAML look like this:
<Grid>
<StackPanel Orientation="Horizontal">
<Button Name="btn_Test" Height="100" Width="100" VerticalAlignment="Center" HorizontalAlignment="Center" Content="1"/>
<Button Name="btn_XXX" Height="100" Width="100" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{Binding vorname}" Margin="20"/>
<Label VerticalAlignment="Top" Background="Red" Width="100" Height="40" Foreground="Black" Content="{Binding vorname, FallbackValue=GEHT_NICHT, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>

Click Menu to call UserControl to MainWindow's Grid

I want to click the menu “Now Playing” then call UserControl to MainWindow's Grid
MainWindow.xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Menu Height="30" VerticalAlignment="Top">
<MenuItem Height="30" Header="Now Playing" x:Name="NowPlaying" Click="NowPlaying_Click" />
<MenuItem Height="30" Header="Music Library" Click="MenuItem_Click" />
<MenuItem Height="30" Header="Play Schedule" />
<MenuItem Height="30" Header="Control" />
<MenuItem Height="30" Header="Option" />
</Menu>
<Grid Margin="0,30,0,0" x:Name="MainBoard">
(UserControl"NowPlaying")
</Grid>
</Grid>
MainWindow.xaml.vb
Private Sub NowPlaying_Click(sender As Object, e As RoutedEventArgs) Handles NowPlaying.Click
Dim MainWindow = TryCast(System.Windows.Window.GetWindow(Me), MainWindow)
Dim MainWindowBoard = MainWindow.MainBoard
Dim NowPlayingBoard As UserControl = New NowPlaying
#???
End Sub
UserControl.xaml:
<Grid>
<Grid Width="800" Margin="0,0,0,100"/>
<Grid Margin="0,350,0,0" Background="#FFFFDADA">
<Slider Margin="10,10,10,0" VerticalAlignment="Top" Height="30"/>
</Grid>
</Grid>
You add controls to a Panel e.g. Grid by using the Panel.Children property.
Your code can be simplified. As the event handler is defined in the code-behind, you already have direct access to all its fields and properties by simply using Me. Calling Window.GetWindow is redundant.
Private Sub NowPlaying_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim nowPlayingControl As UserControl = New NowPlaying()
Me.MainBoard.Children.Add(nowPlayingControl)
End Sub
My Answer:
Private Sub NowPlaying_Click(sender As Object, e As RoutedEventArgs) Handles NowPlaying.Click
Dim NowPlayingBoard As UserControl = New NowPlaying
Me.MainBoard.Children.Clear()
Me.MainBoard.Children.Add(NowPlayingBoard)
End Sub

Click a Button from UserControl to set a value to MainWindow's columndefinition

I want to write a code from UserControl's Button to set value to MainWindow's ColumnDefinition.
When clicked button I need change to this:
<ColumnDefinition Width="0" MaxWidth="400" MinWidth="10" x:Name="MainMenu" x:FieldModifier="public" />
Below is my code:
MainWindow.xaml
<Grid Margin="0,0,0,0">
<local:DockPanelTop />
<Grid Margin="5,45,5,25" x:Name="MainGrid" x:FieldModifier="public">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" MaxWidth="400" MinWidth="10" x:Name="MainMenu" x:FieldModifier="public" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
DockPanelTop.xaml
<UserControl x:Class="DockPanelTop"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<DockPanel LastChildFill="False" VerticalAlignment="Top" Background="Gray" Margin="0,0,0,0" Height="40">
<Button x:Name="HideMenu" Content="Hidden
Menu" Width="50" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="9" />
</DockPanel>
</UserControl>
DockPanelTop.xaml.vb
Public Class DockPanelTop
Private Sub HideMenu_Click(sender As Object, e As RoutedEventArgs) Handles HideMenu.Click
("When clicked set value to columndefinition width to "0" ")
End Sub
End Class
I find nothing the code sample on web in VB to the DockPanelTop.xaml.vb :( Please help me.
Sry, bad English.TY.
You can get a reference to the parent window using the shared Window.GetWindow method. Try this:
Private Sub HideMenu_Click(sender As Object, e As RoutedEventArgs)
Dim window = TryCast(System.Windows.Window.GetWindow(Me), MainWindow)
If (window IsNot Nothing) Then
Dim columnDef = window.MainGrid.ColumnDefinitions(0)
Dim width = New GridLength(0)
columnDef.Width = New GridLength(0)
columnDef.MinWidth = 0.0
End If
End Sub
My Answer:
Public Sub HideMenu_Click(sender As Object, e As RoutedEventArgs) Handles HideMenu.Click
Dim window = TryCast(System.Windows.Window.GetWindow(Me), MainWindow)
Dim columnDef0 = window.MainGrid.ColumnDefinitions(0)
Dim columnDef0Width = window.MainGrid.ColumnDefinitions(0).Width
If (window IsNot Nothing) Then
If columnDef0Width.Value <= 10 Then
columnDef0.Width = New GridLength(150)
columnDef0.MinWidth = 10.0
ElseIf columnDef0.Width.Value > 10 Then
columnDef0.Width = New GridLength(10)
columnDef0.MinWidth = 10.0
End If
End If
End Sub

How do I add, save and load items to a listview in WPF

About two weeks ago I started to develop in WPF and, since I only developed in WinForms, I ran into common problems but managed to find the solution for them. However, currently I'm stuck at something: adding items with multiple columns (via visual basic code, not xaml) into a listview.
I'm not sure if it's best to use a Listview or a DataGrid control for this but basically I want the user to be able to add favourite songs to a list, save them to a file and load the file whenever the app is opened. The listview currently has three columns: Artist, Song and Status.
When I was programming in WinForms, I used to do this:
Dim Song As New ListViewItem
Form1.ListView1.Items.Add(Song)
Song.Text = TextBox1.Text
Song.SubItems.Add(TextBox2.Text)
Song.SubItems.Add(TextBox3.Text)
Then, to save:
Dim Song As New ListViewItem
Form1.ListView1.Items.Add(Song)
Song.Text = TextBox1.Text
Song.SubItems.Add(TextBox2.Text)
Song.SubItems.Add(TextBox3.Text)
Try
Dim myWriter As New IO.StreamWriter(PATH_DATABASE)
For Each myItem As ListViewItem In Form1.ListView1.Items
myWriter.WriteLine(myItem.Text & "|" & myItem.SubItems(1).Text & "|" & myItem.SubItems(2).Text & "|" & myItem.SubItems(3).Text
Next
myWriter.Close()
Catch ex As Exception
MsgBox("Error: " & ex.Message, vbCritical, "Error")
End Try
I've been searching and I've found that I need to use binding so I've tried this:
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Windows
Public Structure Song
Public _artist As String
Public _title As String
Public _status As String
Property Artist() As String
Get
Return _artist
End Get
Set(ByVal Value As String)
_artist = Value
End Set
End Property
Property Title() As String
Get
Return _title
End Get
Set(ByVal Value As String)
_title = Value
End Set
End Property
Property Status() As String
Get
Return _status
End Get
Set(ByVal Value As String)
_status = Value
End Set
End Property
End Structure
Public Class WINDOW_AddSong
Dim songs As New ObservableCollection(Of Song)
Private Sub Button1_Click(sender As Object, e As RoutedEventArgs) Handles Button1.Click
Dim Song As New ListViewItem
For Each wnd As Window In Application.Current.Windows
If wnd.GetType Is GetType(MainWindow) Then
DirectCast(wnd, MainWindow).Listview1.Items.Add(Alimento)
Alimento.Content = New Song() With {._artist = "Lol", ._title = "Lol2", ._status = "Lol3"}
End If
Next
End Sub
End Class
And in the XAML listview:
<GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Artist}"/>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}"/>
This works however I'm not sure if this is the WPF-way of doing things.
However, I'm stuck at the saving process:
Try
Dim myWriter As New IO.StreamWriter(PATH_DATABASE)
For Each wnd As Window In Application.Current.Windows
If wnd.GetType Is GetType(MainWindow) Then
For Each myItem As ListViewItem In DirectCast(wnd, MainWindow).Listview1.Items
myWriter.WriteLine(Song, Artist, Status)
Next
End If
Next
myWriter.Close()
Catch ex As Exception
MsgBox("Error: " & ex.Message, vbCritical, "Error")
End Try
This doesn't work.
Also, PATH_DATABASE is just a directory.
To summarise, could an expert review my code and check if I'm doing things "right" and, if possible, could you help me with the saving and loading process?
Thanks.
I just updated your structure (I used a class, just force of habit) to use automatic property values which are available in recent versions of VS. The default implementation of properties is built in along with the backer fields. It is used just as before.
You are on the right track with ObservableCollection but you you need to implement INotifyPropertyChanged by adding the Event PropertyChanged and providing the Sub OnPropertyChanged to raise the event.
Set up the bindings on the controls and set the ItemsSource ot the ListView to your ObservableList.
To save Import System.Text so you can use a StringBuilder. The loop through the list to build the string to save to a text file.
I didn't spend any time trying to make the XAML Windows look nice. Pardon the ugliness.
Class MainWindow
Public Songs As New ObservableCollection(Of Song)
Protected Sub OnLoad(sender As Object, e As RoutedEventArgs)
Songs.Add(New Song("Nirvana", "Smells Like Teen Spirit", "Open"))
Songs.Add(New Song("John Lennon", "Imagine", "In Stock"))
Songs.Add(New Song("U2", "One", "Unknown"))
Songs.Add(New Song("Michael Jackson", "Billie Jean", "Open"))
lvSongs.ItemsSource = Songs
End Sub
Private Sub BtnAdd_Click(sender As Object, e As RoutedEventArgs)
Dim frm As New frmAdd
frm.mainForm = Me 'send the instance of the current form to the new form
frm.ShowDialog()
End Sub
Private Sub SaveList()
Dim sb As New StringBuilder
For Each item As Song In Songs
sb.AppendLine($"{item.Artist}|{item.Title}|{item.Status}")
Next
'call sb.ToString and write it to a .txt file
End Sub
End Class
MainWindow XAML
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_BindComboBox"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Loaded="OnLoad"
Name="root">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Margin="10" Name="lvSongs" Grid.Row="0">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Name: " />
<TextBox x:Name="txtArtist"
Text="{Binding Artist, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
FontWeight="Bold"/>
<TextBlock Text=", " />
<TextBlock Text="Age: " />
<TextBox Text="{Binding Title}"
FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBox Text="{Binding Status}" />
<TextBlock Text=")" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button x:Name="btnAdd" Grid.Row="1" Height="25" Width="100" Content="Add a Song" Click="BtnAdd_Click"/>
</Grid>
</Window>
The Song class
Public Class Song
Implements INotifyPropertyChanged
Public Property Artist() As String
Public Property Title() As String
Public Property Status() As String
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
Public Sub New(art As String, Ttl As String, Stat As String)
Artist = art
Title = Ttl
Status = Stat
End Sub
End Class
The Add Window
Public Class frmAdd
Public mainForm As MainWindow
Private Sub BtnAdd_Click(sender As Object, e As RoutedEventArgs)
mainForm.Songs.Add(New Song(txtArtist.Text, txtTitle.Text, txtStatus.Text))
ClearForm()
End Sub
Private Sub ClearForm()
txtArtist.Clear()
txtTitle.Clear()
txtStatus.Clear()
End Sub
End Class
Add Window XAML
<Window x:Class="frmAdd"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_BindComboBox"
mc:Ignorable="d"
Title="frmAdd" Height="172.641" Width="307.547">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Artist" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtArtist" Grid.Column="1" Grid.Row="0" FontSize="16" Width="150" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="Title" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtTitle" Grid.Column="1" Grid.Row="1" FontSize="16" Width="150"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Status" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtStatus" Grid.Column="1" Grid.Row="2" FontSize="16" Width="150"/>
<Button x:Name="btnAdd" Grid.Column="1" Grid.Row="4" Content="Add Song" Click="BtnAdd_Click"/>
</Grid>
</Window>
EDIT
Required Imports
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Text

XAML - DataTemplate : unexplainable exception thrown (Unhandled exception)

Image following 2 datatemplates:
<DataTemplate x:Key="templateGridDeleteBtn">
<Button Tag="{Binding stamnr}" Click="ButtonGridDelete_Click" ToolTipService.ToolTip="Verwijderen aanvraag mutatie">
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<Image Source="../Images/DeleteRed.png" Width="20" Height="20" />
</StackPanel>
</Button>
</DataTemplate>
<DataTemplate x:Key="templateProcessRequest">
<Button Tag="{Binding stamnr}" Click="ButtonProcess_Click" ToolTipService.ToolTip="Verwerken zonder de Wasserij te contacteren">
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<Image Source="../Images/Process.png" Width="20" Height="20" />
</StackPanel>
</Button>
</DataTemplate>
I'm having an Unhandled exception when adding the Click-event to my templateProcessRequest. Yet the code behind them is exactly the same (see below)
Private Sub ButtonGridDelete_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
End Sub
Private Sub ButtonProcess_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
End Sub
If i remove the Click-Event from my second template then the exception isn't thrown. What is the reason of this strange behavior?
Found the problem. It had nothing to do with the XAML itself. The exception was thrown due to inheritance.
This control acts as parent for multiple other documents. And if the method shown in the Click event of the parameter isn't present in the 'sub'-controls then an unhandled exception is thrown.
Example:
MainControl A
=> Has method ButtonProcess_Click
SubControl B inherits MainControl A
=> Has method ButtonProcess_Click
SubControl C inherits MainControl A
=> Doesn't Have method ButtonProcess_Click
An exception will be thrown in SubControl C but not in A or B.

Resources