I've implemented RadCalendar in my Nativescript Angular project.
<GridLayout>
<ScrollView class="page">
<StackLayout class="home-panel">
<Button text="Clear" (tap)="onClearTap()"></Button>
<RadCalendar height="1000px" [viewMode]="viewMode" #mainCalendar
[selectionMode]="selectionMode" [eventSource]="calEvents"
(loaded)="calendarLoaded($event)"
[eventsViewMode]="eventsViewMode"
[selectedDate]="selectedDate" [displayedDate]="selectedDate">
</RadCalendar>
</StackLayout>
</ScrollView>
</GridLayout>
From the constructor, I'm adding an event for today's date.
constructor() {
let eventDate = new Date();
eventDate.setDate(eventDate.getDate());
let event = new CalendarEvent("XXX", eventDate, eventDate, true);
this.calEvents.push(event);
this.mainCalendar.selectedDate = eventDate;
}
I am trying to keep today's date selected by default and events under it listed when a user visits the calendar.
Now a user has to click on today's date to see the events under it.
I tried to keep today's date selected using selectedDate but it's no working.
Can anyone tell me how to do it? Thanks!
Here's a playground link
The constructor code should be moved to NgOnInit.
ngOnInit(): void {
let eventDate = new Date();
eventDate.setDate(eventDate.getDate());
let event = new CalendarEvent("XXX", eventDate, eventDate, true);
this.calEvents.push(event);
this.mainCalendar.selectedDate = eventDate;
}
try put nativeElement like this:
this.mainCalendar.nativeElement.selectedDate = eventDate;
Related
I have a label on my app's main page that is supposed to update every fifteen seconds, but it only updates once and after that, a lot of things stop working. For example, if I try to open a new page after the label updates, the page's title is drawn in the same place as the back button (both of which are generated in the toolbar by Xamarin), and the page's content doesn't load at all. Also, I have a ListView on the page and if I try to select an item (which is supposed to open a new page) it only works the first time, after which point the ListView disappears, but the orange box that appears behind a selected item stays there.
How the label works at the moment is I have a timer in the App class that chooses a random piece of text from a list that I load in the app's OnStart() function (that part works properly) and then fires an event that is supposed to update the label.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Timers;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Partylist.Views;
using Partylist.Models;
namespace Partylist
{
public partial class App : Application, INotifyPropertyChanged
{
// Variable to store the currently selected event.
public static Event selectedEvent;
// Variable to store the currently selected list.
public static PartylistList selectedList;
// Struct to store information about tips.
public struct Tip
{
// A short version of the tip for the banner at the bottom of the screen.
public string Summary { get; set; }
// The full tip, which you can read by clicking the "More" button in the banner.
public string Full { get; set; }
}
// Array of tips.
public List<Tip> tips = new List<Tip>();
// Current tip.
public Tip CurrentTip { get; set; }
// Timer that gets the tip to update.
public Timer tipTimer = new Timer(15000);
// Random number generator for choosing the tip.
public Random rand = new Random();
// Event that tells the tip banners on the pages to update.
public static event EventHandler TipUpdate;
// Constructor.
public App()
{
// Do whatever initialization stuff this does.
InitializeComponent();
// Subscribes the timer's event handling function to its event.
tipTimer.Elapsed += OnTimerElapsed;
// Open the first page: the list of events.
MainPage = new NavigationPage(new EventsPage()) {
BarTextColor = Color.FromHex("FF4081")
};
}
// Loads tips data.
private void LoadTips()
{
// Variable for the assembly.
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
// Variable for the stream I use to read the text file.
Stream tipsStream = assembly.GetManifestResourceStream("Partylist.Resources.tips.txt");
// And a variable for the StreamReader.
StreamReader tipsReader = new StreamReader(tipsStream);
// Read the whole file into the list of tips.
while (!tipsReader.EndOfStream)
{
// Read a line into a "sumamry" variable.
string sum = tipsReader.ReadLine();
// Read another line into a "full" variable.
string full = tipsReader.ReadLine();
// Add an item to the list of tips that uses "summary" as the summary
// and "full" as the full tip.
tips.Add(new Tip()
{
Summary = sum,
Full = full
});
}
// Random index of the chosen tip.
int index = rand.Next(tips.Count);
// Set the current tip as the tip at that index.
CurrentTip = tips.ElementAt(index);
// Start timer (if it needs it).
tipTimer.Start();
}
// Event handling function for when the timer goes off.
private void OnTimerElapsed(object source, ElapsedEventArgs e)
{
// Random index of the chosen tip.
int index = rand.Next(tips.Count);
// Set the current tip as the tip at that index.
CurrentTip = tips.ElementAt(index);
// Fire the event to update the pages' tip banners.
TipUpdate?.Invoke(this, e);
}
// Standard lifecycle events.
protected override void OnStart()
{
// Call a function that loads the tips.
LoadTips();
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
}
In the page's OnAppearing() method, I have the label's text set to the current tip (which at this point is null) and I subscribe the function that updates it to the event that the timer fires.
using Partylist.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EventsPage : ContentPage
{
// Text of the tip banner.
public string BannerText { get; set; }
// List of events, used to populate
// the page's ListView (see the XAML).
public ObservableCollection<Event> EventList { get; set; }
// Constructor.
public EventsPage()
{
// Does all the stuff to make the page
// exist that doesn't involve anything
// specific to this particular page in
// this particular app.
InitializeComponent();
// Set the label's BindingContext to the
// App class so it can update its text.
tipLabel.BindingContext = (App)App.Current;
}
// Runs when the page appears.
protected override void OnAppearing()
{
// Call the regular OnAppearing method.
base.OnAppearing();
// Set the BindingContext of the page to itself.
BindingContext = this;
// Update the ListView.
UpdateListView();
// Set the banner's text to the current tip's sumamry.
tipLabel.Text = ((App)App.Current).CurrentTip.Summary;
OnPropertyChanged("CurrentTip");
// Subscribe the OnTipUpdate function to the tipUpdate event in the app
// class.
App.TipUpdate += OnTipUpdate;
}
// Function to update the ListView whent he page loads or when something changes.
private void UpdateListView()
{
// Set the EventList to a new ObservableCollection
// which will be populated.
EventList = new ObservableCollection<Event>();
// Loop to populate the ObservableCollection.
for (int i = 0; i < Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))
.Length; i++)
{
// Add a new event.
EventList.Add(new Event()
{
// Set the folder name to the name of the folder
// that the even corresponds to.
FolderName = new DirectoryInfo(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i]).Name,
// Sets the date/time created to the folder's
// creation date.
DateCreated = Directory
.GetCreationTime(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i]),
// Sets the date/time last edited to the
// folder's write date.
DateEdited = Directory
.GetLastWriteTime(Directory.GetDirectories(
Environment.GetFolderPath(
Environment.SpecialFolder
.LocalApplicationData))[i])
});
// Set the ItemsSource of the ListView in the
// XAML to the ObservableCollection.
EventsListView.ItemsSource = EventList;
// Calls OnPropertyChanged() which makes the ListView update.
OnPropertyChanged("EventList");
}
}
// Function to go to the "New Event" page.
async void OnNewEventClicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new NewEventPage());
}
// Function for when a ListView item is selected.
async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
App.selectedEvent = (Event)e.SelectedItem;
await Navigation.PushAsync(new ListsPage());
}
// Function to delete an event if the "Delete" context action is selected.
async void OnDelete(object sender, EventArgs e)
{
// Represents the thing to be deleted.
var del = (MenuItem)sender;
// Displays a confirmnation popup and stores the user's answer in a variable.
var answer = await DisplayAlert("Delete this event?",
"Are you sure you want to delete the event: \"" +
((Event)del.CommandParameter).FolderName + "\"?", "Delete", "Cancel");
// If the user accepted, delete the event with the MenuItem that ran this function.
if (answer)
{
Directory.Delete(Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData),
((Event)del.CommandParameter).FolderName), true);
// Set the ItemsSource to null and back to make the ListView update.
EventsListView.ItemsSource = null;
UpdateListView();
}
}
// Function for when the current tip updates.
public void OnTipUpdate(object sender, EventArgs e)
{
// Make the label's text update.
tipLabel.Text = ((App)App.Current).CurrentTip.Summary;
OnPropertyChanged("CurrentTip");
}
}
}
Also, here is the page's XAML in case something is wrong with that.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Partylist.Views.EventsPage"
Title="Events"
BackgroundColor="White">
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="settings_gear.png"
Priority="0"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<!--Main layout of the page-->
<StackLayout>
<!--ListView of the events-->
<ListView x:Name="EventsListView"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!--These contewxt actions are buttons that appear
when you long press the item (Android) or swipe
left (iOS).-->
<ViewCell.ContextActions>
<MenuItem Clicked="OnDelete"
CommandParameter="{Binding .}"
Text="Delete"
IsDestructive="true"/>
</ViewCell.ContextActions>
<!--This is the content that actually appears-->
<StackLayout Padding="20,5">
<Label Text="{Binding FolderName}"
TextColor="#FF7700"
FontSize="Large"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--"New Event" button-->
<Button Text="+ Add New Event"
TextColor="#ff418b"
FontSize="Large"
BackgroundColor="#00ffffff"
Clicked="OnNewEventClicked"/>
<!--The banner at the bottom of the screen that gives tips-->
<Frame BorderColor="#ff418b"
Padding="0">
<FlexLayout Direction="Row"
AlignItems="Stretch"
JustifyContent="SpaceBetween">
<!--The "Tip" icon-->
<Image Source="tip_icon.png"
Margin="10"
FlexLayout.Basis="50"/>
<!--The short version of the tip-->
<Label x:Name="tipLabel"
VerticalTextAlignment="Center"
TextColor="#bb0099"
FontSize="Medium"
FontAttributes="Bold"
FlexLayout.Basis="250"/>
<!--The button that opens up a screen
with tyhe rest of the tip-->
<Button Text="More"
TextColor="White"
FontAttributes="Bold"
FontSize="Medium"
BackgroundColor="#ff418b"
FlexLayout.Basis="100"/>
</FlexLayout>
</Frame>
</StackLayout>
</ContentPage.Content>
</ContentPage>
What am I doing wrong and how do I keep my app from breaking when the label updates?
You need to update the text in Main thread:
Device.BeginInvokeOnMainThread (() => {
label.Text = "Async operation completed";
});
Refer: xamarin.forms.device.begininvokeonmainthread
Creating a Registration page, I need to get the following data from user.
First Name
Last Name
Username
Email
Password
Date of Birth
Gender
User Role
For the last two parameters, I am unable to find how to use radio buttons in Xamarin.Forms. Following is my code for the Registration Page.
<StackLayout BackgroundColor="#30af91" Padding="60">
<Entry Text="{Binding FirstName}" Placeholder="First Name"/>
<Entry Text="{Binding LastName}" Placeholder="Last Name"/>
<Entry Text="{Binding UserName}" Placeholder="Last Name"/>
<Entry Text="{Binding Email}" Placeholder="Email" />
<Entry Text="{Binding Password}" Placeholder="Password" IsPassword="True"/>
<Entry Text="{Binding ConfirmPassword}" Placeholder="Confirm Password" IsPassword="True"/>
<DatePicker MinimumDate="1/1/1948" MaximumDate="12/31/2007"/>
<!--Radio buttons for Gender
1. Male 2.Female-->
<!--Radio Buttons for UserRole
1. Admin 2.Participant-->
<Button Command="{Binding RegisterCommand}" Text="Register"/>
<Label Text="{Binding Message}" />
</StackLayout>
Xamarin forms does not provide Radio Button.
You can either use
1)Switch
2)Picker
or any other component to fulfill your requirement
UPDATE
The xamarin forms update version 4.6 has introduced the Radio button control, Here is the official documentation
I think there is a simpler solution that is fairly easy and requires no libraries. Really a a radio group is just a fancy ListView. You would just need to create a viewModel for each radio button that has a IsSelected flag and switch between 2 images. I had a need to allow a user to select how long a token persisted:
XAML
<ListView
HasUnevenRows="True"
HorizontalOptions="FillAndExpand"
ItemsSource="{Binding Durations}"
ItemSelected="ListView_ItemSelected"
SelectedItem="{Binding SelectedDuration}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
Orientation="Horizontal">
<Image
HeightRequest="18"
IsVisible="{Binding IsSelected}"
Source="radioButtonChecked.png"
WidthRequest="18"/>
<Image
HeightRequest="18"
IsVisible="{Binding IsUnselected}"
Source="radioButtonUnchecked.png"
WidthRequest="18"/>
<Label
Margin="8,0,0,0"
Text="{Binding Caption}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
We create a listview in our content page and listen for the ItemSelected event. Each list item is a horizontal stack panel where we flip between two images depending on the selected state
Code Behind
public partial class LoginPage : ContentPage
{
LoginPageViewModel LoginPageViewModel { get; }
public LoginTwoFactorFrequencyPage ()
{
BindingContext = LoginPageViewModel = new LoginPageViewModel();
InitializeComponent ();
}
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
LoginPageViewModel.UpdateSelected(e.SelectedItem as PersistenceDuration);
}
}
The page's code behind instantiates a view model and calls an UpdateSelected method with the newly selected item on the page's view model*
RadioButton ViewModel
The view model for each radio button:
public class PersistenceDuration : ViewModelBase
{
bool isSelected;
public string Caption { get; set; }
public TwoFactorTokenPersistenceDuration Duration { get; set; }
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged();
OnPropertyChanged("IsUnselected");
}
}
public bool IsUnselected => !IsSelected;
public PersistenceDuration(string caption, TwoFactorTokenPersistenceDuration duration)
{
Caption = caption;
Duration = duration;
IsSelected = false;
}
}
The radio button view model holds selection info and the caption. We make sure to fire OnPropertyChanged whenever the selected state changes
Page ViewModel
public class LoginPageViewModel : ViewModelBase
{
PersistenceDuration duration;
PersistenceDuration selectedDuration;
public ObservableCollection<PersistenceDuration> Durations { get; }
public PersistenceDuration SelectedDuration
{
get => selectedDuration;
set
{
if (value != null)
{
duration = value;
UpdateSelected(duration);
}
OnPropertyChanged();
}
}
public LoginTwoFactorFrequencyViewModel()
{
Durations = new ObservableCollection<PersistenceDuration>(
new List<PersistenceDuration>()
{
new PersistenceDuration(AppResources.Save_code__forever, TwoFactorTokenPersistenceDuration.Forever),
new PersistenceDuration(AppResources.ChatRequireEvery30Days, TwoFactorTokenPersistenceDuration.ThirtyDays),
new PersistenceDuration(AppResources.ChatRequireEveryLogin, TwoFactorTokenPersistenceDuration.None),
});
}
public void UpdateSelected(PersistenceDuration persistenceDuration)
{
foreach (var item in Durations)
item.IsSelected = persistenceDuration == item;
}
}
In the page view model we create a list of radio button view models that the XAML binds to. When we UpdateSelected() all the IsSelected states are updated which trigger binding updates which flip the image.
You will still need to do something about the highlight when someone selects an item, but that is easy enough to find on the internet :)
You can use XLabs plugin from manage NuGets package. After installing you can use like this:
In Xaml:
controls:BindableRadioGroup x:Name="Radiobtn"
In C#:
string[] gender = {"MAlE","FEMALE"}
Radiobtn.Add(gender)
Refer Link
https://github.com/XLabs/Xamarin-Forms-Labs/tree/master/samples/XLabs.Samples/XLabs.Samples/Pages/Controls
You can get the radio button effect without a package. Use Labels with text unicode circle \u26AA or \u25CB. Attach a tab gesture recognizer to each label.
When tapped, change the text of the selected button to unicode circle bullet \u29BF and change the text of the other button(s) back to unicode circle \u26AA.
Test on your preferred platforms as each platform may display somewhat differently. You may need to adjust the font size as you change the text.
If you want real radiobuttons you can xlabs their package (https://github.com/XLabs/Xamarin-Forms-Labs/tree/master/src/Forms/XLabs.Forms/Controls/RadioButton)
Personally I'd just use a picker, Xlabs package hasn't been updated in a while so their might be some bugs in the radiobutton
You can use image as a radio button. When tou you click on it, it can change. It is not a good way to do it though.
This is xaml code:
<Image Scale="0.7" HorizontalOptions="Start" x:Name="radioButton" Source="unRadioBtn.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="radioButton_Clicked"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
And this is .cs:
private void radioButton_Clicked(object sender, EventArgs e)
{
radioButton.Source = "radioBtn.png";
}
Xamarin.Forms 4.6 introduced a new RadioButton control. You can find the documentation here: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/radiobutton
You can use the switch component. Also you can see the implementation for a checkbox component from the XLabs project which is now discontinued, get the code and modify it as you need.
Hint: You're gonna need the custom renderers per platform for it to work .
You need to use Picker
https://developer.xamarin.com/api/type/Xamarin.Forms.Picker/
Actually it is the best alternative to RadionButton On Xamarin.forms
XLabs RadioButton and BindableRadioGroup work well: XLabs RadioButton for Xamarin Forms
Here's a simple Yes/No radio using the BindableRadioGroup:
var answers = new List<string>();
answers.Add("Yes");
answers.Add("No");
var RadioGroup = new XLabs.Forms.Controls.BindableRadioGroup()
{
ItemsSource = answers,
Orientation = StackOrientation.Horizontal
};
Xamarin Forms now provides a Radio Button control.
See docs here:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/radiobutton
As of XF 4.8 this is still experimental and I've not yet used this feature so can't comment on its stability.
I am trying to create a custom component in Nativescript. The component works fine with the static data, I want to add some custom properties to that control, but the are not accessible in the code behind. I am trying to create a MCQ like box or a something similar to radio control, so user can only select one option from the given ones.
CustomControl.xml
<StackLayout orientation="vertical" class="form" loaded="loaded">
<Repeater items="{{ items }}">
<Repeater.itemTemplate>
<StackLayout orientation="vertical" tap="itemTapped" id="{{id}}">
<StackLayout orientation="horizontal" verticalAlignment="center">
<Label text="{{text}}" class="form-field" width="88%"/>
<Label text="{{characterCode}}" visibility="{{visible ? 'visible' : 'collapsed'}}" class="icon"/>
</StackLayout>
<StackLayout class="separator"/>
</StackLayout>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
CustomControl.js
var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
var _component;
var _viewModel = new Observable();
var _selectedId = null;
exports.loaded = function(args){
_component = args.object;
//passing in _component.items as array throws undefined
var items = getInitializedArray(["Some text","Someother text"]);
_viewModel.set("items", items);
_component.bindingContext = _viewModel;
}
exports.itemTapped = function(args){
var id = args.object.id;
if(_selectedId === null){
var item = _viewModel.get("items").getItem(id);
item.visible = true;
_viewModel.get("items").setItem(item, id);
}else{
var item = _viewModel.get("items").getItem(_selectedId);
item.visible = false;
item = _viewModel.get("items").getItem(id);
item.visible = true;
_viewModel.get("items").setItem(item, id);
}
_selectedId = id;
}
function getInitializedArray(data){
var id=0;
var items = data.map((listItem) => {
return {
text: listItem,
characterCode: String.fromCharCode(0xea11),
visible: false,
id: id++
}
});
return new ObservableArray(items);
}
Trying to use it in my page as
<CustomComponents:CustomControl items="{{items}}"/>
But using args.object.items throws undefined property for object.
I have read that I'll have to use dependency-observable and will have to create a plugin. But I am not using any platform specific thing, I am just creating a component with existing ui components and its pretty simple what I want to achieve. Is there a way to bind custom properties? Plugins are too complex for this, How can I achieve it?
After reading the docs and going through various forums and github issues following is what I have found and thanks to Nick lliev' comment.
To give custom properties to your controls you'll have to use the code only technique, I have written a blog http://mobile.folio3.com/creating-custom-controls-in-nativescript/ describing both the techniques showing how to give custom properties to your custom controls.
I am trying to figure out how the best way to use AutoCompleteBox with MVVM Light.
public ICommand AutoComplete
{
get
{
return new RelayCommand<KeyEventArgs>(e =>
{
var txtBox = e.OriginalSource as TextBox;
if (e.Key == Key.Unknown)
{
return;
}
string autoComplete = txtBox.Text + e.Key;
if (autoComplete.Length >= 3)
{
RestClient c = new RestClient("http://localhost:3333/api/store");
RestRequest r = new RestRequest("/GetStoreNames",Method.GET);
r.AddParameter("Name", autoComplete);
r.AddParameter("Latitude", "49");
r.AddParameter("Longitude", "49");
var d = c.BuildUri(r);
c.ExecuteAsync(r, response2 =>
{
var content = response2.Content;
});
}
});
}
}
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyUp">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding AutoComplete, Mode=OneWay}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<toolkit:AutoCompleteBox x:Name="acbStore" Margin="154,196,29,0" VerticalAlignment="Top" RenderTransformOrigin="0.6,0.083" Height="162" MinimumPopulateDelay="500"/>
I did the above but there is a couple problems.
Once I get the results back how do I show them in the auto complete area?
How can I delay it from doing to many requests at once? As you can see I don't want to hit the server before 3 characters are entered but after that it is fair game. I am kinda worried that like 20 requests will be done to the server before the 1st request makes it back leading to wasted bandwidth.
I am assuming you are using KeyDown event or similar? That is not the way you want to do it. Instead, bind the AutoCompleteBox Populating event and set the MinimumPrefixLength on your AutoCompleteBox to 3 so thatPopulating is fired only when you have 3+ characters. To show the list retrieved in your control, the list need to be bound to ItemsSource property then a method needs to be called, PopulateComeplte().
You can see my answer here on a similar Question.
However, it is not MVVM friendly since you need to call a method on your AutoCompleteBox to trigger the control to show the list from your webservice. Take a look at this article for a MVVM-friendly approach, scroll down to "Bonus: MVVM-friendly asynchronous filtering" section.
Hi i have a requirement i need your help for it:-
I have a set of phone numbers of type string separated by a comma , now i want to assign each phone number to hyperlink and on click of it will invoke the PhoneCallTask and make a call to that particular phone number.
1) So , how to assign each phone number to a hyperlink(should we dynamically generate the hyperlink? in c# codebehind)
2)if so , how to dynamically generate hyperlink buttons and add it to a stack panel present in a listbox ?
3)How would i know which Hyperlinkbutton is clicked?
4)All HyperlinkButton's would point to same hyperlink click event?
Thanks in Advance.
In your MainPage.xaml, add this inside the ContentPanel control:
<ListBox x:Name="PhoneNumbersList">
<ListBox.ItemTemplate>
<DataTemplate>
<HyperlinkButton Content="{Binding}" Click="PhoneNumberHyperlinkButton_Click" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then, on the MainPage code behind, add this code:
public MainPage()
{
InitializeComponent();
var phoneNumbers = new string[] { "9999999", "8888888", "7777777" };
PhoneNumbersList.ItemsSource = phoneNumbers;
}
private void PhoneNumberHyperlinkButton_Click(object sender, RoutedEventArgs e)
{
var phoneNumberHyperlinkButton = (HyperlinkButton)sender;
var phoneNumber = (string)phoneNumberHyperlinkButton.Content;
new Microsoft.Phone.Tasks.PhoneCallTask()
{
PhoneNumber = phoneNumber
}.Show();
}
That's it!