c# windows phone 8.1 get button content as a string - c#

I'm new to c# and wp development.
On "Holding" I want the Content value of the button as a string in my c# code.
<Grid>
<Pivot>
<PivotItem>
<Grid>
<Button x:Name="Venue1" Content="Venue1" HorizontalAlignment="Left" Margin="30,0,0,0"VerticalAlignment="Top" Width="342" Height="102" Grid.Row="1" Holding="Holding"/>
</Grid>
</PivotItem>
</Pivot>
</Grid>
I thought it was pretty straightforward and did this but doesn't work.
TextToSpeech is a method that takes a string and reads it out. It reads out "Windows.UI.Xaml.Controls.Grid"... why?
private async void Holding(object sender, HoldingRoutedEventArgs)
{
await TextToSpeech(this.Content.ToString());
}

Try this :-
private async void Holding(object sender, HoldingRoutedEventArgs)
{
var obj = sender as Button;
var content = obj.Content;
await TextToSpeech(content);
}
What are you doing wrong is by using this. Here this does not belong to button but for the page itself. In place of this you have to use the corresponding button object that i have already shown how to use.
For further reference see This Keyword
you can also use name of the button to get its content that is little bit hard coded.

It is pretty straightforward :)
await TextToSpeech(this.Venue1.Content.ToString());

Related

How to Navigate from One Page to Another in WPF

I have a MainWindow.XAML and CustomersView.XAML.
When I click the Customer Button on MainWindow , I want to navigate to CustomersView.XAML and palong with that need to pass few parameters.
I can use NavigationService but is only available with Pages and not Window.Hyperlink is not an option at this moment.
This might be fairly simple thing but not sure how can I implement this using MVVM and with out any third party control.
private void Navigate_Click(object sender, RoutedEventArgs e)//By Prince Jain
{
this.NavigationService.Navigate(new Uri("Page3.xaml", UriKind.Relative));
}
There are many options to navigate from one window to another in WPF. You can use a frame in your MainWindow and navigate all your pages right inside your Frame.
<Window
x:Class="NavigationSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<DockPanel>
<Frame x:Name="_mainFrame" />
</DockPanel>
</Window>
From code, you can tell the frame to navigate, like so:
_mainFrame.Navigate(new Page1());
Which just so happens to be a helpful shortcut to:
_mainFrame.NavigationService.Navigate(new Page1());
Or if you using any framework like PRISM, you are allowed to create a Shell where you can define regions and let your pages navigate to that.
Navigation Using the Prism Library 5.0 for WPF
Simple Way in XAML:
<Button HorizontalAlignment="Right" Name="continueButton" Width="75"
Margin="0,0,8,11" Height="23" VerticalAlignment="Bottom"
Click="continueButton_Click">
Navigate
</Button>
C#:
private void continueButton_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.GoForward();
//or
this.NavigationService.Navigate("Second.xaml")
}
In MVVM XAML:
<Button Command="{x:Static Views:Commands.NavigateHelp}"
Content="Help"/>
In Views (We have a Commands.cs file that contains all of these):
public static RoutedCommand NavigateHelp = new RoutedCommand();
In the page constructor, you can connect the two:
CommandBindings.Add(new CommandBinding(Commands.NavigateHelp,
NavigateHelpExecute));
NavigateHelpExecute can be in the code behind (which is what we do), hook into a ViewModel event handler, or whatever. The beauty of this is that you can disable other navigation like so:
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, null));

How to load UI on navigated page(2nd page) according to the grid clicked on first page

I am working on a windows store 8.1 app, I have added Grids in MainPage.xaml using List in MainPage.xaml.cs
MainPage.xaml
<GridView Margin="20" x:Name="main" SelectionMode="None" IsItemClickEnabled="True" ItemClick="main_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="Red" Width="250" Height="200">
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Stretch="UniformToFill" Source="{Binding ImageLocation}"/>
<TextBlock Text="{Binding Title}" Grid.Row="1" FontSize="28" />
<TextBlock Text="{Binding SubTitle}" Grid.Row="2" FontSize="16" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
MainPage.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
List<data> myList = new List<data>();
myList.Add(new data()
{
ImageLocation = #"Assets/network.png",
iName = "NetWork",
SubTitle ="Network",
Title = "Network"
});
myList.Add(new data()
{
ImageLocation = #"Assets/fb.png",
iName = "Facebook",
SubTitle = "Facebook",
Title = "Facebook"
});
main.ItemsSource = myList;
}
private void main_ItemClick(object sender, ItemClickEventArgs e)
{
Frame.Navigate(typeof(ListView));
}
I want that when someone click on any of the grids, a TextBlock in ListView page show which grid was clicked in MainPage .
This will be a challenge to explain without showing you in code, but here goes...
Hopefully you have created two pages so far. MainPage.xaml that holds your GridView. And a DetailsPage.xaml that will have the layout to show one item.
In the code-behind of MainPage.xaml, like you have in your sample code, you handle the ItemCLick of the GridView, but you want to get the Id of the item clicked, not the item itself. The reason for this is that you want to pass a string, and not a complex object.
In your handler, the event args (e) has a property called ClickedItem that will be the item you are binding to. Let's pretend it's a UserObject you are binding to. In your handler do something like this:
var user = e.ClickedItem as UserObject;
this.Frame.Navigate(typeof(DetailPage), user.Id.ToString());
So, what's happening here? Almost the same code you had before. Except you are navigating to the type of the second page instead of anything else. You are also passing in (the second argument in the Navigate method) the exact record you want to show.
Then in your DetailPage.xaml code-behind you ned to override the OnNavigatedTo method. This method is what is invoked when the Navigation framework directs to the page. It's has a NavigationPararmeter passed to it that you can use to extract the key you passed.
I think it's actually args.Parameter you want to use. You can parse it to an integer and use that to fetch the individual record you have somehow in memory in your application.
var id = int.Parse(args.Parameter);
var user = YourFactory.GetUser(id);
The reason I shifted from this is how you do it to "I think this is how it works" is because although the basic framework operates like this, most developers do not use it like this. Most developers implement something like Prism.StoreApps which introduces not only a lightweight MVVM framework, but also a sophisticated NavigationService that lets you inject parameters directly into an auto-associated view model.
But based on the simplicity of your question, try not to pay attention to that last bit. I explained the basic workflow using the in-box framework. It works just fine, and it will get the job done. When you are ready to write a more advanced implementation you can investigate Prism.StoreApps
More info: http://msdn.microsoft.com/en-us/library/windows/apps/xx130655.aspx
Best of luck!

Getting html to display in xaml

I have tried phone:Webbrowser which does not automatically size to the required amount.
I have tried many textbox and richttextbox property extension libraries, I cannot get any to work.
I want to know how people get html into textboxes or richtextboxes in windows phone 8.
Argh, I have spent 2 evenings on this now! doh!
Context:
I am calling an API that is returning html (why oh god why)... I want to bind the returned html to a textbox or richtextbox or if I haveeee to, a phone:webbrowser.
Textbox and richtextbox do not support html.
phone:webbrowser does not adjust its height according to what's inside the document. You can supposedly do it by enabling javascript and calling window.external.Notify() but I couldn't get it to work quite right...
Moving on from the above problem, even if I did get the phone:webbrowser to work, if for test purposes I make the width 500 and height 500, I can see my html string as plain text rather than the webcontrol correctly parsing html... doh!
Just try this way.
your xaml:
<Grid x:Name="ContentGrid" Grid.Row="1">
<phone:WebBrowser HorizontalAlignment="Left" Margin="20,50,0,0" Name="webBrowser1" VerticalAlignment="Top" Height="500" Width="430" />
</Grid>
in your code:
public MainPage()
{
InitializeComponent();
webBrowser1.Loaded += WebBrowser_OnLoaded;
}
private void WebBrowser_OnLoaded(object sender, RoutedEventArgs e)
{
webBrowser1.Navigate(new Uri("readme.htm", UriKind.Relative));
}
Hope it helps

Windows Phone 8.1 Loading Images from Remote URLs Placeholder

I'm messing around with some windows phone development as I'm new to it coming from an Android background.
I am using "theCatAPI" to load a random picture of a cat and show it, then when the picture is clicked, or the button at the bottom of the screen, the image refreshes to a new one.
I have the following so far:
XAML:
<Page
x:Class="CatFactsPics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CatFactsPics"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="LayoutRoot">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TitlePanel -->
<StackPanel Grid.Row="0" Margin="24,17,0,28">
<TextBlock Text="My Application" Style="{ThemeResource TitleTextBlockStyle}" Typography.Capitals="SmallCaps"/>
<TextBlock Text="page title" Margin="0,12,0,0" Style="{ThemeResource HeaderTextBlockStyle}"/>
</StackPanel>
<!--TODO: Content should be placed within the following grid-->
<Grid Grid.Row="1" x:Name="ContentRoot">
<Image HorizontalAlignment="Center" Stretch="UniformToFill" VerticalAlignment="Center" x:Name="KittyPic" Tapped="KittyPic_Tapped"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" x:Name="newPic" Click="newPic_Click" >New Kitty</Button>
</Grid>
</Grid>
</Page>
and in the page.cs:
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
KittyPic.Source = new BitmapImage(myUri);
}
...
private void newPic_Click(object sender, RoutedEventArgs e)
{
Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
BitmapImage bmi = new BitmapImage();
bmi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bmi.UriSource = myUri;
KittyPic.Source = bmi;
}
I have a couple of questions:
1) is this the correct way of doing things? In Android I'd try and do things asynchronously to avoid stalling the UI thread. That being said, I don't appear to be having any issues with things the way they are now. I'm not familiar with the Windows way of doing things, and haven't found any resources giving any explanation or advice on doing so.
2) There is a delay in displaying the new picture causing a short (couple of second) period where the image view turns black, before the new image reappears. Is there a way of setting it up so either the old picture remains until the new one is physically ready to be displayed, or alternatively display a placeholder "loading" image until the new one can replace it.
Any other advice or tips on how to do things would be great, thanks.
1) With your current code you do not block the UI thread as yes you are setting the URI on the UI thread, but the actually loading of the image is done on another thread automatically. (For doing manually downloading of images, strings etc, you will probably use async/await to avoid locking the UI thread).
2) The image goes black because you change the ImageSource before the new image has loaded. There are as you mention several ways to deal with this. Common for most of them though is that you will want to use the ImageOpened and ImageFailed events on the Image control, which triggers whenever the image is done loading (or an error occurred, for example no internet connection). Here is an example of displaying a loading bar while it is loading, which just hides/shows the loading progress:
In the page.xaml file:
<Grid Grid.Row="1" x:Name="ContentRoot">
<Image x:Name="KittyPic" Tapped="KittyPic_Tapped" ImageOpened="KittyPic_ImageOpened" ImageFailed="KittyPic_ImageFailed" />
<StackPanel x:Name="LoadingPanel" VerticalAlignment="Center">
<ProgressBar IsIndeterminate="True" IsEnabled="True" />
<TextBlock Text="Loading image..." HorizontalAlignment="Center" />
</StackPanel>
</Grid>
And in the page.xaml.cs file
private void KittyPic_Tapped(object sender, TappedRoutedEventArgs e)
{
LoadingPanel.Visibility = Visibility.Visible;
Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
BitmapImage bmi = new BitmapImage();
bmi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bmi.UriSource = myUri;
KittyPic.Source = bmi;
}
private void KittyPic_ImageOpened(object sender, RoutedEventArgs e)
{
LoadingPanel.Visibility = Visibility.Collapsed;
}
private async void KittyPic_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
LoadingPanel.Visibility = Visibility.Collapsed;
await new MessageDialog("Failed to load the image").ShowAsync();
}
Instead of the TextBlock and ProgressBar you could of course show whatever you want, or for example swapping between two images to keep showing the old one.
For other advice I think when you got used to the basics is to take a look at data bindings which is very helpful and powerful. Also take a look at this article about MVVM pattern.
1) is this the correct way of doing things?
No. It's not. You should definitely adopt the MVVM pattern and detach your business logic from your view - meaning you shouldn't create bitmap images or request/assign such remote image URL's in your view's code-behind. You should be doing such stuff in your ViewModel and bind them to your View.
So in your case there will be an Uri (or a string where you will assign the remote URL) property in your ViewModel (which implements INotifyPropertyChanged) then in your View you will be binding it like this:
<!--TODO: Content should be placed within the following grid-->
<Grid Grid.Row="1" x:Name="ContentRoot">
<BitmapImage UriSource="{Binding BackGroundImage}" CreateOptions="BackgroundCreation" />
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" x:Name="newPic" Click="newPic_Click" >New Kitty</Button>
</Grid>
Whenever you set the BackGroundImage property you will be raising an event called;
RaisePropertyChanged("BackGroundImage") -> This is the classical MVVM approach.
So that your view will be aware of the fact that the BackGroundImage is changed and it will load it automatically. (But note that if you just provide a string for this BackGroundImage - you will have to use a converter, a string to Uri converter, since it only accepts Uri's for remote images)
2) "...Is there a way of setting it up so either the old picture remains until the new one is physically ready to be displayed, or alternatively display a placeholder "loading" image until the new one can replace it."
I suggest going with displaying a 'loading' image. I experienced the exact same problem as you do here and my workaround for this was inserting a loading image and setting it's opacity value to 0.1 - along with the actual image. While you are switching between remote URL's, when the previous image disappears the opaque loading image appears and when the next actual image is loaded the loading image is not displayed because new image is overwriting it.

display the documentlibrary folders in windows 8 app

i'm getting the documentlibrary folders. but i don't know how to display the geeting folders in a MainPage.Xaml (design page).
here is my code:
var folders = await KnownFolders.DocumentsLibrary.GetFoldersAsync();
if anyone guide me. Thanks in advance.
Let's assume you've a ListView to show all the folders. And on click of a button, you want to show list of folders in DocumentsLibrary. For this, use following XAML:
<Button Content="Button" HorizontalAlignment="Left" Margin="216,172,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
<ListView x:Name="FolderList" HorizontalAlignment="Left" Height="100" Margin="216,328,0,0" VerticalAlignment="Top" Width="830">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Now, in code behind write following code:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
var folders = await Windows.Storage.KnownFolders.DocumentsLibrary.GetFoldersAsync();
var data = folders.ToList<Windows.Storage.StorageFolder>();
FolderList.ItemsSource = data;
}
This will show you all the folders within the DocumentsLibrary in ListView.
Hope, it helps.
You need to use a ListView or GridView or ListBox in XAML (depending on what you want to do with it) and bind it to the folders list. Then you need an ItemTemplate to specify what you want displayed e.g. folder name, path, size etc

Categories

Resources