I am parsing some JSON data using Newtonsoft.NET for my WP8 app in C#/XAML and everything works fine except the binding of NavigationUri to the HyperlinkButton. Here is the DataTemplate of my databound LongListSelector:
<DataTemplate>
<StackPanel Margin="10 10 10 20" Background="{StaticResource PhoneAccentBrush}">
<TextBlock Text="{Binding MovieTitle }" TextWrapping="Wrap" FontSize="18" />
<TextBlock Text="{Binding ImdbCode }" TextWrapping="Wrap" FontSize="18" />
<HyperlinkButton NavigateUri="{Binding ImdbLink}">View on IMDB</HyperlinkButton>
<Image Source="{Binding MovieCover}" Width="300" Height="300" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding ImdbLink}" TextWrapping="Wrap" FontSize="18" />
</StackPanel>
</DataTemplate>
This way everything is loaded correctly but the HyperLinkButton doesn't navigate to the Uri.
What should I do to make sure the navigation works?
If it is not possible with HyperLinkButton then can I add a regular button to which I could pass the url so that OnClick event can navigate to url.
Assuming the url is correct the webbrowser can be activated like this:
XAML
<HyperlinkButton NavigateUri="{Binding ImdbLink}"
Click="NavigateButton_Click">View on IMDB</HyperlinkButton>
C#
private void NavigateButton_Click(object sender, RoutedEventArgs e)
{
var hyperlinkButton = sender as HyperlinkButton;
if(hyperlinkButton == null)
{
return;
}
ShowInBrowser(hyperlinkButton.NavigateUri);
}
private void ShowInBrowser(Uri url)
{
Microsoft.Phone.Tasks.WebBrowserTask wbt =
new Microsoft.Phone.Tasks.WebBrowserTask();
wbt.Uri = url;
wbt.Show();
}
This is because you have no RequestNavigate method. Try:
<HyperlinkButton NavigateUri="{Binding ImdbLink}" RequestNavigate="Hyperlink_RequestNavigate">View on IMDB</HyperlinkButton>
and in your code behind for the view put
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
or however you want to deal with that click event (i.e. open a new webview with that as the url)
Related
I'm working on Windows Phone 8.1 RT project and i want to get my binding item when mapcontrolSP tapped.
<Maps:MapControl x:Name="Map" MapServiceToken="abcdef-abcdefghijklmno">
<Maps:MapItemsControl x:Name="mapitem" ItemsSource="{Binding}">
<Maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="mapcontrolSP" Orientation="Horizontal" Background="Red" Tapped="ItemStckPanel">
<Image Source="Assets/ico-venue.png" Height="45" Width="45"
Maps:MapControl.Location="{Binding Geopoint}"
Maps:MapControl.NormalizedAnchorPoint="{Binding Anchor}"/>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5">
<TextBlock FontSize="15" Foreground="White" Text="{Binding name}"/>
<TextBlock FontSize="15" Foreground="White" Text="{Binding address}"/>
<TextBlock FontSize="15" Foreground="White" Text="{Binding distance}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Maps:MapItemsControl.ItemTemplate>
</Maps:MapItemsControl>
</Maps:MapControl>
I create a tapped event on the StackPanel element but item is null:
private void ItemStckPanel(object sender, TappedRoutedEventArgs e)
{
var item = sender as FsqBasicItem;
MessageDialog dialog = new MessageDialog(item.name);
dialog.ShowAsync();
}
How can i get item ?
Fast solution:
private void ItemStckPanel(object sender, TappedRoutedEventArgs e)
{
var stackPanel = sender as StackPanel;
var item = stackPanel.DataContext as FsqBasicItem;
if(item != null)
{
MessageDialog dialog = new MessageDialog(item.name);
dialog.ShowAsync();
}
}
In my Windows/Windows Phone Universal App, I have ListView with a MenuFlyout in my XAML layout. The ListView includes a list of people. Tapping on a list item reveals the flyout with options to email or call the person. Right now I am using the Tag property of the MenuFlyoutItem to hold the email address and phone number, but I also want to be able to get the name of the person so I can send that when I open the email composer or phone dialer.
I am using the Tag element to store the basic information, but I want to access the name. How do I do this? Using extra properties? Somehow accessing the data binding of the parent object?
XAML:
<ListView
x:Name="itemPositions"
AutomationProperties.AutomationId="ItemListView"
AutomationProperties.Name="Items In Group"
TabIndex="1"
Grid.Row="1"
ItemsSource="{Binding Positions}"
SelectionMode="None"
IsSwipeEnabled="false"
Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Tapped="Grid_Tapped">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem IsEnabled="{Binding IsFilled}" Tag="{Binding Email}" x:Name="sendEmail" Text="email" Click="sendEmail_Click" />
<MenuFlyoutItem IsEnabled="{Binding IsFilled}" Tag="{Binding Phone}" x:Name="sendCall" Text="call" Click="sendCall_Click" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Visibility="{Binding IsVerified, Converter={StaticResource BoolToInvisible}}" Margin="0,0,0,5" Background="Firebrick" Width="10" Height="70" />
<Border Visibility="{Binding Required, Converter={StaticResource BoolToVisible}}">
<Border Grid.Column="0" Visibility="{Binding IsFilled, Converter={StaticResource BoolToInvisible}}" Margin="0,0,0,5" Background="Gold" Width="10" Height="70" />
</Border>
<StackPanel Margin="10,0,0,10" Grid.Column="1">
<TextBlock Text="{Binding PositionName}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Text="{Binding DisplayName}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C#:
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null) FlyoutBase.ShowAttachedFlyout(element);
}
private async void sendEmail_Click(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Email.EmailMessage mail = new Windows.ApplicationModel.Email.EmailMessage();
mail.Subject = "Leadsheet Position Assignment";
mail.To.Add(new Windows.ApplicationModel.Email.EmailRecipient(element.Tag.ToString()));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
}
private void sendCall_Click(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI(element.Tag.ToString(), "");
}
I thin you should be able to do this for example by checking the DataContext of clicked Grid or MenuItem:
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
Item yourItem = (sender as Grid).DataContext as Item;
FrameworkElement element = sender as FrameworkElement;
if (element != null) FlyoutBase.ShowAttachedFlyout(element);
}
// you can also do the same in your menu items:
private async void sendEmail_Click(object sender, RoutedEventArgs e)
{
Item yourItem = (sender as MenuFlyoutItem).DataContext as Item;
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Email.EmailMessage mail = new Windows.ApplicationModel.Email.EmailMessage();
mail.Subject = "Leadsheet Position Assignment";
mail.To.Add(new Windows.ApplicationModel.Email.EmailRecipient(element.Tag.ToString()));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
}
Item above is your ItemClass which you use in Positions set as ItemsSource. Once you have the clicked item, the rest should be easy. With this you also no longer need to bind in Tag property.
I have a web browser which is storing all the visited websites. There is just one issue, I would like it for the user to click on one of the records and then it should open in the webbrowser.
Once the user has navigated to a page, this method is called with the url:
public List<String> urls;
public string selectedURL;
public MainPage()
{
InitializeComponent();
listBox.DataContext = urls;
}
private void getHistory(string url)
{
urls.Add(url);
listBox.DataContext = null;
listBox.DataContext = urls;
}
private void listBoxtrend_Tap(object sender, GestureEventArgs e)
{
selectedURL = "";
var selected = listBox.SelectedValue as Item;
selectedText = selected.ItemString;
MessageBox.Show(selectedURL);
browserSearch(selectedURL);
}
This is then displayed into a textblock on a pivot page:
<phone:Pivot Margin="0,0,0,0">
<phone:PivotItem Header="" Margin="0,-104,0,0">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="72"/>
<RowDefinition Height="696"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#FF5E667B" >
</Grid>
</phone:PivotItem>
<phone:PivotItem Margin="0,-104,0,0" Header="">
<Grid>
<ListBox ItemsSource="{Binding Item}" Foreground="RoyalBlue" Name="listBox"
TabIndex="10" Tap="listBox_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" FontSize="26" HorizontalAlignment="Left"
x:Name="txtHistory" Text="{Binding ItemString}"
VerticalAlignment="Top" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PivotItem>
</phone:Pivot>
I have tried to put a click event, but there is one way to tell which record is being clicked. Is there a way to use the SelectionChanged event handler. And is there a better way to store this data, maybe in a array or list which then can be saved to IsolatedStorage.
Thank you in advance :)
If you need any more details please comment and I will be happy to explain in further detail :)
It's better if you would have the data you're going to display within a Listbox, I mean the Url's. So that you could easily get whatever the data you want from the clicked item. Make sure that you bind the source for your Listbox.
your xaml:
<ListBox ItemsSource="{Binding Item}" Foreground="RoyalBlue"
Height="395" HorizontalAlignment="Center"
Margin="12,111,0,0" Name="listBox"
VerticalAlignment="Top" Width="438"
TabIndex="10" Tap="listBox_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" FontSize="26" HorizontalAlignment="Left"
x:Name="txtHistory" Text="{Binding ItemString}"
VerticalAlignment="Top" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And then from your tap event handler of the Listbox
private async void listBoxtrend_Tap(object sender, GestureEventArgs e)
{
selectedText = "";
var selected = listBox.SelectedValue as Item;
selectedText = selected.ItemString;
MessageBox.Show(selectedText);
await Launcher.LaunchUriAsync(new Uri("give the url"));//here should be the selectedText
}
These can be referable for more:
Getting selected value of listbox windows phone 7
LIstbox Selected Item content to textblock
Hope it helps!
I'm making an atom reader for Windows Phone. The mainpage.xaml.cs code looks like this:
void ywc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
StringReader sr = new StringReader(e.Result);
var reader = XmlReader.Create(sr);
var document = XDocument.Load(reader);
XNamespace atom = "http://www.w3.org/2005/Atom";
XNamespace media = "http://search.yahoo.com/mrss/";
var YTitems = from entry in document.Descendants(atom + "entry")
select new RSSFeed
{
ImageSRC = entry.Element(media + "group").Element(media + "thumbnail").Attribute("url").Value,
Title = entry.Element(atom + "title").Value,
pubDate = entry.Element(atom + "published").Value.Substring(0, 10),
VideoURL = entry.Element(media + "group").Element(media + "content").Attribute("url").Value
};
YoutubeList.ItemsSource = YTitems.ToList();
}
private void screenshot_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Uri uri = new Uri("insertyoutubeurihere");
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = uri;
webBrowserTask.Show();
}
The mainpage.xaml code looks like this:
<phone:LongListSelector Margin="0,0,-22,0" Name="YoutubeList">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="12,2,0,4" Width="Auto">
<Image x:Name="screenshot" Source="{Binding Path=ImageSRC}" Width="150" Tap="screenshot_Tap"/>
<StackPanel Width="311" Margin="8,-7,0,0">
<TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap" Margin="10,0" Style="{StaticResource PhoneTextLargeStyle}" FontSize="{StaticResource PhoneFontSizeMedium}" />
<TextBlock Text="{Binding Path=pubDate}" TextWrapping="Wrap" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
I don't really know how I can link the uri to the corresponding VideoURL.
So when he user taps, than it opens the webpage with the url of the video.
You can use a Command binding. Instead of two textblocks you can use a button or Hyperlink. Bind the Command property of the button or hyperlink to an ICommand property of your viewmodel.
More information about ICommand: http://msdn.microsoft.com/library/vstudio/system.windows.input.icommand
In case you are using MVVM Light, you could also take a look at the RelayCommand class.
this:
<StackPanel>
<HyperlinkButton Height="310"
Width="200"
NavigateUri="{Binding Path=ImageSRC}"
Name="hyperlinkButton1"
TargetName="_blank">
<HyperlinkButton.Background>
<ImageBrush ImageSource="{Binding Path=ImageSRC}"/>
</HyperlinkButton.Background>
</HyperlinkButton>
...
</StackPanel>
Just use this:
System.Diagnostics.Process.Start(urlString);
...
this should launch the url in the default browser, no matter what platform you're on (WinXP, WinVista, Win7, Win8, etc)...
keep in mind that it expects a full url to recognize it as that and launch the browser...
Here is my xaml of the Panorama page item.
<controls:PanoramaItem x:Name="deeln" Header="Deelnemers" Style="{StaticResource subtitle}">
<!--Double line list with image placeholder and text wrapping-->
<ListBox Margin="12,0,-12,0" ItemsSource="{Binding ItemsDeelnemer}" x:Name="lbDeelnemer" SelectionChanged="lbDeelnemer_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal" Margin="0,0,0,17">
<TextBlock Foreground="Black" TextWrapping="Wrap" Text="{Binding LineNr}" Style="{StaticResource PhoneTextExtraLargeStyle}" ></TextBlock>
<StackPanel Width="430" Height="100">
<TextBlock Foreground="Black" TextWrapping="Wrap" Text="{Binding LineNaamWielrenner1}" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="35"></TextBlock>
<TextBlock Foreground="Black" TextWrapping="Wrap" Text="{Binding LineNaamWielrenner2}" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="35"></TextBlock>
</StackPanel>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>
Here is my code in the Panorama page.
private void lbDeelnemer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
#region go to specific deelnemerinfo screen
// If selected index is -1 (no selection) do nothing
if (lbDeelnemer.SelectedIndex == -1)
return;
// Navigate to the new page
if (lbDeelnemer.SelectedIndex == 0)
{
NavigationService.Navigate(new Uri("/DeelnemerInfo.xaml", UriKind.Relative));
//NavigationService.Navigate(new Uri("/DeelnemerInfo.xaml?selectedItem=" + lbDeelnemer.SelectedIndex, UriKind.Relative));
}
// Reset selected index to -1 (no selection)
lbDeelnemer.SelectedIndex = -1;
#endregion
}
Here is my code from the non panorama page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//second try
string strItemIndex;
if (NavigationContext.QueryString.TryGetValue("goto", out strItemIndex))
PanoramaControl.DefaultItem = MyPanorama.Items[Convert.ToInt32(strItemIndex)];
base.OnNavigatedTo(e);
//first try
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
DataContext = App.ViewModel.ItemsDeelnemer[index];
}
}
My problem, I want to navigate like you do with a default databound application. You click on the first listitem and you go to a new page (non panorama).
It looks simple but i can't find it.
Try binding the tag attribute to the index/itemvalue
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<HyperlinkButton Tag="{Binding FileName}" Click="location_Click"/>
<TextBlock Text="{Binding DateCreated}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
navigate accordingly
private void location_Click(object sender, RoutedEventArgs e)
{
HyperlinkButton clicked = (HyperlinkButton)sender;
string uri = "/noteapp;component/ViewEdit.xaml?id=" + clicked.Tag;
NavigationService.Navigate(new Uri(uri, UriKind.Relative));
}
and on panaroma page use this something like this to retrieve the value
filename = NavigationContext.QueryString["id"];
var storage = IsolatedStorageFile.GetUserStoreForApplication();
using (var file = storage.OpenFile(filename, FileMode.Open))