Calculator dont get a result when i click = - xamarin

im at the end of my first Xamarin Project but when im want a answer to a mathematic operation i get an error as Xamarin.Forms.Label
Maybe it has to do with the xaml file and the part for the OnCalculate Eventhandler in the xaml is as follows:
<Button Text="="
Grid.Row="5"
Grid.Column="3"
Grid.ColumnSpan="2"
TextColor="Black"
FontSize="36" BorderRadius="0"
Clicked="OnCalculate" />
...
And the .cs as follows:
void OnCalculate(object sender, EventArgs e)
{
if (currentState == 2)
{
var result = OperatorHelper.Calculate(firstNumber, secondNumber, myoperator);
this.resultText.Text = resultText.ToString();
firstNumber = result;
currentState = -1;
}
}
Thanks in advance
...

you are doing this
var result = OperatorHelper.Calculate(firstNumber, secondNumber, myoperator);
this.resultText.Text = resultText.ToString();
when you probably want to do this (show the value of result in your output)
var result = OperatorHelper.Calculate(firstNumber, secondNumber, myoperator);
this.resultText.Text = result.ToString();

Related

How to check list of selected images BindableLayout in Xamarin

I'm trying to upload images in Xamarin to Server via API.
.xaml
<Grid x:Name="pickimg" Grid.Row="0" Grid.Column="1" HorizontalOptions="End" VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<Image Margin="0">
<Image.Source>
<FontImageSource Color="#ddd" Size="22" FontFamily="MaterIcon" Glyph="{x:Static local:FontIconsClass.Camera}"/>
</Image.Source>
</Image>
</StackLayout>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="pickimg_Tapped" />
</Grid.GestureRecognizers>
</Grid>
<StackLayout HorizontalOptions="FillAndExpand">
<StackLayout x:Name="listImg" Orientation="Horizontal">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame HasShadow="False" Padding="0" IsClippedToBounds="True" CornerRadius="4">
<Image HeightRequest="70" WidthRequest="70" Aspect="AspectFill" Source="{Binding .}"/>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
.xaml.cs
This is how I display the list of selected photos:
async void pickimg_Tapped(System.Object sender, EventArgs e)
{
var pickResult = await MediaGallery.PickAsync(5, MediaFileType.Image);
if(pickResult?.Files == null)
{
return;
}
else
{
var imgList = new List<ImageSource>();
foreach (var img in pickResult?.Files)
{
var stream = await img.OpenReadAsync();
imgList.Add(ImageSource.FromStream(() => stream));
}
BindableLayout.SetItemsSource(listImg, imgList);
}
}
Everything seems fine. And I have 1 button to post the image to the Server:
private async void bt_addfeed_Clicked(object sender, EventArgs e)
{
var getResult = listImg;//How can I check and get the list of images in listImg?
if(getResult == null)
{
return;
}
else
{
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("", content);......
}
}
How can I check and get the list of images in listImg? Please solutions, Thanks
Update...
List<ImageSource> imgList = new List<ImageSource>();
async void pickimg_Tapped(System.Object sender, EventArgs e)
{
var pickResult = await MediaGallery.PickAsync(5, MediaFileType.Image);
if(pickResult?.Files == null)
{
return;
}
else
{
foreach (var img in pickResult?.Files)
{
var stream = await img.OpenReadAsync();
imgList.Add(ImageSource.FromStream(() => stream));
}
BindableLayout.SetItemsSource(listImg, imgList);
}
}
private async void bt_addfeed_Clicked(object sender, EventArgs e)
{
var getResult = imgList;
if(getResult == null)
{
return;
}
else
{
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("", content);......
}
}
How can getResult get .FileName and .OpenReadAsync()?
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
you are declaring imgList as a local variable, so it only has scope inside the method where you declare it
var imgList = new List<ImageSource>();
instead, declare it as a class level variable so it will be accessible throughout the page
// do this inside the class body, but NOT within a specific method
List<ImageSource> imgList = new List<ImageSource>();

How to make a button disabled or hidden in settings page while navigating from login page

I have got two buttons in the MainPage, one is Login button and another Navigate button. When the user click on the Navigate button, it should display Home, Settings and other tabs, but would like to make one of the button in settings page as hidden or disabled ?
I have tried the below code with `MessagingCenter' and received in Settings, but it is not working, could someone please have a look !
//Settings.xaml given below;
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="soccerapp.Settings" BackgroundColor="#755f89" Title="Settings">
<AbsoluteLayout>
<!-- Normal Page Content -->
<StackLayout AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All">
<Label HeightRequest="50" FontSize="18" TextColor="White" HorizontalOptions="Center" Text="Please enter today's soccer status-" />
<Label Text="{Binding SoccerStatus}"></Label>
<Label Text="{Binding CurrentDate}"></Label>
<Button x:Name="button1"
Text="Click here !"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Clicked="OnButtonClicked" />
</StackLayout>
</AbsoluteLayout>
</ContentPage>
//MainPage.xaml.cs :
public async void NavigateButton_OnClicked(object sender, EventArgs e)
{
var tabbedPage = new TabbedPage();
tabbedPage.Children.Add(new Home("Welcome"+' '+emailEntry.Text+' '+",have a nice day!"));
tabbedPage.Children.Add(new Settings(soccerAvailability, emailEntry.Text));
await Navigation.PushAsync(tabbedPage);
MessagingCenter.Send<object>(this, "TurnOffButton");
}
public Settings(string emailText)
{
InitializeComponent();
emailTextVal = emailText;
MessagingCenter.Subscribe<object>(this, "TurnOffButton", (sender) =>
{
button1.IsVisible = false;
});
}
// login button code follows:
public async void Button_Clicked(object sender, System.EventArgs e)
{
this.IsBusy = true;
await Task.Delay(TimeSpan.FromMilliseconds(1000));
string emailText = emailEntry.Text;
string passwordText= passwordEntry.Text;
if(!string.IsNullOrWhiteSpace(emailEntry.Text) && !string.IsNullOrWhiteSpace(passwordEntry.Text))
{
if(ValidateEmail(emailText) == true)
{
int count = (from x in conn.Table<PlayerDetails>().Where(x => x.Email == emailText) select x).Count();
if (count!= 0)
{
try
{
List<PlayerDetails> myList = (from x in conn.Table<PlayerDetails>().Where(x => x.Email == emailText && x.Password == passwordText) select x).ToList();
if(myList.Count() > 0)
{
var tabbedPage = new TabbedPage();
PlayerDetails playerDetails = new PlayerDetails();
SoccerAvailability soccerAvailability = new SoccerAvailability();
tabbedPage.Children.Add(new Home(emailEntry.Text));
tabbedPage.Children.Add(new Settings(soccerAvailability, emailEntry.Text));
await Navigation.PushAsync(tabbedPage);
var profilePicTollbarItem = new ToolbarItem()
{
Icon = "LF.PNG"
};
profilePicTollbarItem.Clicked += OnProfilePicClicked;
tabbedPage.ToolbarItems.Add(profilePicTollbarItem);
}
else
{
this.IsBusy = false;
await DisplayAlert("Notification", "No such email or password", "Cancel");
}
}
catch (NullReferenceException ex)
{
if(ex!=null)
Debug.WriteLine("Something is thrown ! " + e.ToString());
}
finally
{
IsBusy = false;
}
}
else
{
this.IsBusy = false;
await DisplayAlert("Notification", "Unable to find the user details", "Cancel");
}
}
else
{
this.IsBusy = false;
await DisplayAlert("Notification", "Email is not a valid one", "Cancel");
}
}
else
{
this.IsBusy = false;
await DisplayAlert("Notification","Input details cannot be blank", "Cancel");
}
}
it would be a lot simpler to just pass a bool in the constructor of Settings
public Settings(string emailText, bool ShowButton = false)
{
...
button1.IsVisible = ShowButton;
}
then when you create the Settings page for your two different code paths pass in the appropriate value
// hide button - when called from Navigate
tabbedPage.Children.Add(new Settings(emailEntry.Text, false));
// show button - when called from Login
tabbedPage.Children.Add(new Settings(emailEntry.Text, true));

Windows Phone 8 audioplayer Exception

I got Exception of System.Windows.Markup.XamlParseException occurred in System.Windows.ni.dll,
System.ArgumentException occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
my MainPage.xaml:
<Slider Name="timelineSlider" Margin="0,185,0,376" ValueChanged="SeekToMediaPosition"/>
<TextBlock Height="51" HorizontalAlignment="Left" Margin="27,334,0,0" x:Name="TitleTextBlock" Text="Title:" VerticalAlignment="Top" FontSize="28" Foreground="{StaticResource PhoneAccentBrush}" Width="400" />
<TextBlock Height="39" HorizontalAlignment="Left" Margin="27,383,0,0" x:Name="ArtistTextBlock" Text="Artist:" VerticalAlignment="Top" FontSize="24" FontStyle="Italic" Foreground="White" Width="400" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="37,559,0,0" x:Name="StartTextBlock" Text="00:00:00" VerticalAlignment="Top" Width="100" />
<TextBlock Height="30" HorizontalAlignment="Left" TextAlignment="Right" Margin="327,559,0,0" x:Name="EndTextBlock" Text="00:00:00" VerticalAlignment="Top" Width="88" />
<Slider HorizontalAlignment="Left" Margin="43,200,0,0" VerticalAlignment="Top" Width="395" Name="SongSlider" ManipulationCompleted="SoundSlider_ManipulationCompleted"/>
My MainPage.xaml.cs file is:
private void NotProvided()
{
if (BackgroundAudioPlayer.Instance.Track != null)
{
// show soung info
TitleTextBlock.Text = BackgroundAudioPlayer.Instance.Track.Title
ArtistTextBlock.Text = BackgroundAudioPlayer.Instance.Track.Artist;
// handle slider and texts
SongSlider.Minimum = 0;
SongSlider.Maximum = BackgroundAudioPlayer.Instance.Track.Duration.TotalMilliseconds;
string text = BackgroundAudioPlayer.Instance.Track.Duration.ToString();
EndTextBlock.Text = text.Substring(0, 8);
}
if (null != BackgroundAudioPlayer.Instance.Track)
{
txtCurrentTrack.Text = BackgroundAudioPlayer.Instance.Track.Title +
" by " +
BackgroundAudioPlayer.Instance.Track.Artist;
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
playButton.Content = "pause";
txtCurrentTrack.Text = BackgroundAudioPlayer.Instance.Track.Title +
" by " +
BackgroundAudioPlayer.Instance.Track.Artist;
}
else
{
playButton.Content = "play";
txtCurrentTrack.Text = "";
}
}
private DispatcherTimer dispatcherTimer = new DispatcherTimer();
private void startTimer()
{
// start timer to check position of the song
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 500);
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// song is playing
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
// handle slider
SongSlider.Minimum = 0;
SongSlider.Value = BackgroundAudioPlayer.Instance.Position.TotalMilliseconds;
SongSlider.Maximum = BackgroundAudioPlayer.Instance.Track.Duration.TotalMilliseconds;
// display text
string text = BackgroundAudioPlayer.Instance.Position.ToString();
StartTextBlock.Text = text.Substring(0, 8);
text = BackgroundAudioPlayer.Instance.Track.Duration.ToString();
EndTextBlock.Text = text.Substring(0, 8);
}
}
private void SoundSlider_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
// get slider value
int sliderValue = (int)SongSlider.Value;
// create timespan object with milliseconds (from slider value)
TimeSpan timeSpan = new TimeSpan(0, 0, 0, 0, sliderValue);
// set a new position of the song
BackgroundAudioPlayer.Instance.Position = timeSpan;
}
private void PrevButton_Click(object sender, RoutedEventArgs e)
{
// skip to previous song
BackgroundAudioPlayer.Instance.SkipPrevious();
// handle text and slider
playButton.Content = "Pause";
SongSlider.Value = 0;
}
private void NextButton_Click(object sender, RoutedEventArgs e)
{
// skip to next song
BackgroundAudioPlayer.Instance.SkipNext();
// handle text and slider
playButton.Content = "Pause";
SongSlider.Value = 0;
}

WP7 - VisualTreeHelper to loop through all ListBox Items

I need to create a new ListBox based on items that are selected (checked). The following code actually worked if I only had like 20 items on the ListBox, but adding more items make it crash. Can anybody know how to make it work, or have a different aproach? Is there a limite for looping through a listBox?
// worked fine for 20 items,
// but my actual list contems 95 items...
private void btnCreateNewList_Click(object sender, RoutedEventArgs e)
{
int totalItemsCB = ListCheckBoxVocabulary.Items.Count;
for (int ii = 0; ii < totalItemsCB-1; ii++)
{
ListBoxItem item = this.ListCheckBoxVocabulary.ItemContainerGenerator.ContainerFromIndex(ii) as ListBoxItem;
CheckBox thisCheckBox = FindFirstElementInVisualTree<CheckBox>(item);
if (thisCheckBox.IsChecked == true)
{
dataPlayListSource.Add(new SampleData() { Text = thisCheckBox.Content.ToString() + " | " + ii });
// this.PlayListCheckBoxVocabulary.UpdateLayout();
this.PlayListCheckBoxVocabulary.ItemsSource = dataPlayListSource;
}
}
}
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
and xaml:
<controls:PivotItem Header="Vocabulary" >
<ListBox x:Name="ListCheckBoxVocabulary" Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<StackPanel Margin="0,0,0,17" Width="432">-->
<CheckBox x:Name="cbVocabulary" Content="{Binding Text}" Checked="CheckBox_Checked" Unchecked="UncheckBox" />
<!--</StackPanel>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
The list is virtual - controls are created as they are needed and potentially reused (I think).
Your options are to turn the ListBox to not be virtualized (override the template, and for the container, instead of a SerializedStackPanel, choose a regular StackPanel).
Your other (and preferable) option is to do the checking via Data Binding. Way easier and faster in most situations.

parse xml and binding data to listbox

It's very simple task, but I struggle for hours.
I have parse xml from web sources and bind them to listbox. Now I want to make an index for each items binded to list box, something like this:
1.Title 2.Title 3.Title
Author Author Author
Date Date Date
Here is what I have so far:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="stkPnl" Orientation="Horizontal" Margin="15,0" MouseEnter="stkPnl_MouseEnter" MouseLeave="stkPnl_MouseLeave">
<Image x:Name="imageAV" Source="{Binding avlink}" Height="80" Width="80"
Stretch="UniformToFill" MouseLeftButtonUp="imageAV_MouseLeftButtonUp" ImageFailed="imageAV_ImageFailed"/>
<StackPanel Orientation="Vertical" Margin="10,0,0,0" MouseLeftButtonUp="StackPanel_MouseLeftButtonUp">
<TextBlock Text="{Binding nickname}" Width="Auto" />
<TextBlock Text="{Binding track}" FontWeight="Bold" Width="Auto"/>
<TextBlock Text="{Binding artist}" Width="Auto"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
and MainPage.xaml.cs
private void DoWebClient()
{
var webClient = new WebClient();
webClient.OpenReadAsync(new Uri("http://music.mobion.vn/api/v1/music/userstop?devid="));
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (var reader = new StreamReader(e.Result))
{
string s = reader.ReadToEnd();
Stream str = e.Result;
str.Position = 0;
XDocument xdoc = XDocument.Load(str);
var data = from query in xdoc.Descendants("user")
select new mobion
{
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
listBox.ItemsSource = data;
}
}
As you see I only have nickname, track and artist, if I want to add an index that increase for each listboxItem, how can I do that?
Thank you for reading this question.
I know it's ugly, but it's an idea: Create a wrapper class for around your mobion class:
public class mobionWrapper : mobion
{
public int Index { get; set; }
}
Instead of selecting mobion instances you select mobionWrapper instances:
var data = from query in xdoc.Descendants("user")
select new mobionWrapper
{
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
After binding the your data, set the Index property of your wrapper class:
listBox.ItemsSource = data;
for(int i = 0; i < listBox.Items.Count; i++)
{
var item = listBox.Items[i] as mobionWrapper;
item.Index = i + 1;
}
Now you need a new TextBlock and bind it to the Index property:
<TextBlock Text="{Binding Index}" Width="Auto" />
Worked for me. Keep in mind that the index might be invalid after sorting or filtering the data display.
Assuming you've an appropriate field in you mobion class (which you can bind to in the view), you can use an incrementing counter to populate this field as the document is iterated over.
int[] counter = { 1 };
var data = from query in xdoc.Descendants("user")
select new mobion
{
index = counter[0]++,
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
Note that counter is an array of int rather than just an int to prevent accessing a modified closure.

Resources