Scroll of RichTextBlock in windows 8 apps - windows

I have a RichTextBlock in a ScrollViewer. The content of the RichTextBlock is very long. How can I scroll those text inside RichTextBlock?
I want to implement scrolling with in the Rich text Block as the text goes on appending with in the text block. Here the input has been given through a text box & those text of text box are appended into Rich Text block.
<Grid Background="{StaticResource
> ApplicationPageBackgroundThemeBrush}">
> <Grid.RowDefinitions>
> <RowDefinition Height="0.6*" />
> <RowDefinition Height="0.4*" />
> </Grid.RowDefinitions>
>
> <Grid Grid.Row="0"
> Width="1200"
> Height="350"
> Background="#FFFF">
> <ScrollViewer x:Name="scrollViewerChat"
> Width="1200"
> Height="350"
> HorizontalScrollBarVisibility="Disabled"
> HorizontalScrollMode="Disabled"
> VerticalScrollBarVisibility="Visible"
> VerticalScrollMode="Auto">
> <RichTextBlock x:Name="rchChatBlock"
> Grid.Row="0"
> Width="1200"
> Height="350"
> FontSize="40"
> Foreground="Black"
> ScrollViewer.VerticalScrollBarVisibility="Visible">
> <Paragraph x:Name="rchParagraph" ScrollViewer.VerticalScrollBarVisibility="Visible">
> <Run />
> </Paragraph>
> </RichTextBlock>
> </ScrollViewer>
> </Grid>
>
> <TextBox x:Name="txtBoxChat"
> Grid.Row="1"
> Width="1200"
> Height="100"
> FontSize="40"
> />
> <Button Grid.Row="1"
> Width="150"
> Height="50"
> HorizontalAlignment="Left
> VerticalAlignment="Bottom"
> Click="btnSend_Click"
> Content="Send" />
> </Grid>
>
>
>
>
> private void btnSend_Click(object sender, RoutedEventArgs e)
> {
> LoadData2();
> }
>
> private void LoadData2()
> {
> string input = txtBoxChat.Text;
> string pattern = " ";
> string[] substrings = Regex.Split(input, pattern);
> for (var i = 0; i < substrings.Length; i++)
> {
> var item = substrings[i];
> Run run1 = new Run();
> Run run2 = new Run();
> run1.Text = item;
> rchParagraph.Inlines.Add(run1);
>
> string k = " ";
> run2.Text = k;
> rchParagraph.Inlines.Add(run2);
>
> }
> Run run3 = new Run();
> run3.Text = "\n";
> rchParagraph.Inlines.Add(run3);
>
> }

I am not sure what event you want to use, but I'll let you decide. Then do this:
public void CauseScroll()
{
var box = new RichTextBlock();
var scroll = Children(box).First(x => x is ScrollViewer) as ScrollViewer;
scroll.ChangeView(null, scroll.ScrollableHeight, null);
}
public static IEnumerable<FrameworkElement> Children(FrameworkElement element)
{
Func<DependencyObject, List<FrameworkElement>> recurseChildren = null;
recurseChildren = (parent) =>
{
var list = new List<FrameworkElement>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement)
list.Add(child as FrameworkElement);
list.AddRange(recurseChildren(child));
}
return list;
};
var children = recurseChildren(element);
return children;
}
That will scroll to the bottom.
Best of luck!

Related

Xamarin CarouselView throws OutOfRangeException when ItemsSource changes and Positon is not 0

I have a Xamarin Forms App with a Carousel View and my plan is to filter the result by the Priorities shown in a Bottom Tap Bar.
When the View is on the first card, everything works fine, but if you hit one of the filters from a different card, then the first one, a System.ArgumentOutOfRangeException exception got fired.
I tried already a lot of things to set the position of the Carousel View to 0, but in vain.
using the CarouselView_PositionChanged event => not working
using the TabHost_SelectedTabIndexChanged event => not working
setting the property of the CarouselView by the selectedIndex changed from the Tab View from the ViewModel => not working
turn it into a CollectionView and everything is working => just looks ugly 🤮
Here the page
<?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:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:viewModels="clr-namespace:AmsXamarin.ViewModels"
xmlns:fontAwesome="clr-namespace:FontAwesome"
xmlns:cells="clr-namespace:AmsXamarin.Cells"
xmlns:tabs="http://sharpnado.com"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="AmsXamarin.Views.SnagListX.SnagListPage"
x:Name="mySnagListPage">
<ContentPage.BindingContext>
<viewModels:SnagListViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<xct:TabSelectionChangedEventArgs x:Key="TabSelectionChangedEventArgs" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Command="{Binding ShowMyJobsCommand}"
Order="Primary"
Priority="0"
Text="{Binding MyJobsTitle,Mode=TwoWay}">
</ToolbarItem>
<ToolbarItem Command="{Binding AddFaultCommand}"
Order="Primary"
Priority="0">
<ToolbarItem.IconImageSource>
<FontImageSource FontFamily="FAS"
Glyph="{x:Static fontAwesome:FontAwesomeIcons.Plus}"
Color="{AppThemeBinding Dark={StaticResource Third},Light={StaticResource Primary}}"
Size="Large" />
</ToolbarItem.IconImageSource>
</ToolbarItem>
<ToolbarItem Command="{Binding AcceptCommand}"
Order="Primary"
Priority="0">
<ToolbarItem.IconImageSource>
<FontImageSource FontFamily="FAS"
Glyph="{x:Static fontAwesome:FontAwesomeIcons.UserCheck}"
Color="{AppThemeBinding Dark={StaticResource Third},Light={StaticResource Primary}}"
Size="Large" />
</ToolbarItem.IconImageSource>
</ToolbarItem>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout>
<Label Style="{StaticResource LabelLarge}"
Text="Snag List"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<StackLayout>
<IndicatorView x:Name="snagListIndicator"
Margin="0,10,0,0"
IndicatorColor="LightGray"
SelectedIndicatorColor="LightGray"
IndicatorSize="6" />
<RefreshView Command="{Binding RefreshCommand}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
Style="{StaticResource BaseRefreshView}">
<CarouselView x:Name="snagListCV"
Margin="10"
IndicatorView="snagListIndicator"
ItemsLayout="HorizontalList"
ItemsSource="{Binding SnagListPriorities.SnagListApps}"
CurrentItem="{Binding SnagListItem}"
Position="{Binding PositionIdx,Mode=OneWay}"
PositionChanged="CarouselView_PositionChanged"
Loop="False"
IsEnabled="{Binding IsNotBusy}">
<CarouselView.EmptyView>
<StackLayout Padding="12">
<Label Style="{StaticResource LabelMedium}"
HorizontalOptions="Center"
Text="{Binding EmptyMessage,Mode=TwoWay}" />
</StackLayout>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
<DataTemplate>
<cells:SnagListCardX />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</RefreshView>
</StackLayout>
<tabs:TabHostView x:Name="TabHost"
Margin="13,0,13,10"
BackgroundColor="{AppThemeBinding Dark={StaticResource Third},Light={StaticResource Fourth}}"
CornerRadius="30"
IsSegmented="True"
Orientation="Horizontal"
TabType="Fixed"
SelectedIndex="{Binding SelectedIndex,Mode=TwoWay}"
Shades="{StaticResource LightBottomShadow}">
<tabs:TabHostView.Behaviors>
<xct:EventToCommandBehavior EventName="SelectedTabIndexChanged"
Command="{Binding SelectedCommand}"
EventArgsConverter="{StaticResource TabSelectionChangedEventArgs}" />
</tabs:TabHostView.Behaviors>
<tabs:TabHostView.Tabs>
<tabs:BottomTabItem Style="{StaticResource BottomTabsMedium}"
Label="All">
<tabs:BottomTabItem.Badge>
<tabs:BadgeView Style="{StaticResource BadgeViewBase}"
BackgroundColor="{StaticResource All}"
TextColor="White"
Text="{Binding SnagListPriorities.All,Mode=TwoWay}" />
</tabs:BottomTabItem.Badge>
</tabs:BottomTabItem>
<tabs:BottomTabItem Style="{StaticResource BottomTabsMedium}"
Label="High"
StyleClass="">
<tabs:BottomTabItem.Badge>
<tabs:BadgeView Style="{StaticResource BadgeViewBase}"
BackgroundColor="{StaticResource High}"
TextColor="White"
Text="{Binding SnagListPriorities.High,Mode=OneWay}" />
</tabs:BottomTabItem.Badge>
</tabs:BottomTabItem>
<tabs:BottomTabItem Style="{StaticResource BottomTabsMedium}"
Label="Medium">
<tabs:BottomTabItem.Badge>
<tabs:BadgeView Style="{StaticResource BadgeViewBase}"
BackgroundColor="{StaticResource Medium}"
TextColor="Black"
Text="{Binding SnagListPriorities.Medium,Mode=TwoWay}" />
</tabs:BottomTabItem.Badge>
</tabs:BottomTabItem>
<tabs:BottomTabItem Style="{StaticResource BottomTabsMedium}"
Label="Low">
<tabs:BottomTabItem.Badge>
<tabs:BadgeView Style="{StaticResource BadgeViewBase}"
BackgroundColor="{StaticResource Low}"
TextColor="Black"
Text="{Binding SnagListPriorities.Low,Mode=TwoWay}" />
</tabs:BottomTabItem.Badge>
</tabs:BottomTabItem>
</tabs:TabHostView.Tabs>
</tabs:TabHostView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And the view model
using AmsXamarin.Helpers;
using AmsXamarin.Models;
using AmsXamarin.Services;
using MvvmHelpers;
using MvvmHelpers.Commands;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using Command = MvvmHelpers.Commands.Command;
namespace AmsXamarin.ViewModels
{
public class SnagListViewModel : BaseViewModel
{
readonly ISnagListService snagListService;
List<SnagListAppX> SnagListAppXs;
SnagListAppX snagListItem;
public SnagListAppX SnagListItem
{
get { return snagListItem; }
set
{
snagListItem = value;
OnPropertyChanged();
}
}
SnagListPriorities snagListPriorities;
public SnagListPriorities SnagListPriorities
{
get { return snagListPriorities; }
set
{
snagListPriorities = value;
OnPropertyChanged();
}
}
public AsyncCommand AddFaultCommand { get; }
public AsyncCommand AcceptCommand { get; }
public Command RefreshCommand { get; }
public Command SelectedCommand { get; }
public Command ShowMyJobsCommand { get; }
string emptyMessage;
public string EmptyMessage
{
get { return emptyMessage; }
set
{
emptyMessage = value;
OnPropertyChanged();
}
}
int positionIdx;
public int PositionIdx
{
get { return positionIdx; }
set
{
positionIdx = value;
OnPropertyChanged();
}
}
int selectedIndex;
public int SelectedIndex
{
get => selectedIndex;
set => SetProperty(ref selectedIndex, value);
}
string myJobsTitle = "My Jobs";
int staffId;
public string MyJobsTitle
{
get { return myJobsTitle; }
set
{
myJobsTitle = value;
OnPropertyChanged();
}
}
bool myJobsEnabled = true;
bool updateProperty = false;
public bool AcceptToolBar { get; set; }
public SnagListViewModel()
{
SnagListItem = new SnagListAppX();
SnagListPriorities = new SnagListPriorities()
{
SnagListApps = new ObservableRangeCollection<SnagListAppX>()
};
SnagListAppXs = new List<SnagListAppX>();
AddFaultCommand = new AsyncCommand(ShowAddSnagListItem);
AcceptCommand = new AsyncCommand(ShowModalAccept);
SelectedCommand = new Command(Selected);
RefreshCommand = new Command(Refresh);
staffId = 0;
ShowMyJobsCommand = new Command(ShowModalMyJobs);
snagListService = DependencyService.Get<ISnagListService>();
Device.BeginInvokeOnMainThread(async () =>
{
await GetSnagListItems();
});
}
async Task GetSnagListItems()
{
try
{
IsBusy = true;
EmptyMessage = "Loading...";
SnagListPriorities slp = await snagListService.GetSnagLists(false, true);
SnagListPriorities.SnagListApps.Clear();
SnagListPriorities = slp;
SnagListAppXs.Clear();
SnagListAppXs.AddRange(slp.SnagListApps);
EmptyMessage = SnagListAppXs.Count == 0 ? "Good Job! \r\n\r\nCurrently nothing to fix" : "";
IsBusy = false;
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "Ok");
}
}
void Selected()
{
//PositionIdx = 0;
//OnPropertyChanged(nameof(PositionIdx));
//FilterSnagList();
Refresh();
}
void FilterSnagList()
{
var allJobs = SnagListAppXs;
if (staffId != 0) allJobs = allJobs.Where(x => x.StaffId == staffId).ToList();
if (updateProperty) OnPropertyChanged(nameof(SnagListPriorities));
if (selectedIndex > 0) allJobs = allJobs.Where(sli => sli.Priority == selectedIndex).ToList();
SnagListPriorities.SnagListApps.Clear();
//SnagListPriorities.SnagListApps = new ObservableRangeCollection<SnagListAppX>(allJobs);
SnagListPriorities.SnagListApps.AddRange(allJobs);
//OnPropertyChanged(nameof(SnagListPriorities.SnagListApps));
updateProperty = false;
}
void ShowModalMyJobs()
{
staffId = myJobsEnabled ? int.Parse(Settings.StaffIdSetting) : 0;
MyJobsTitle = myJobsEnabled ? "All Jobs" : "My Jobs";
AcceptToolBar = !myJobsEnabled;
myJobsEnabled = !myJobsEnabled;
SelectedIndex = 0;
updateProperty = true;
}
void Refresh()
{
IsBusy = true;
var allJobs = SnagListAppXs.Where(s => s.StaffId == 115);
SnagListPriorities.SnagListApps.Clear();
SnagListPriorities.SnagListApps.AddRange(allJobs);
IsBusy = false;
}
}
}
looks a bit messy, but wanted to show, that I tried already a lot of things.
Last try was a simple RefreshView.
It works as long as the itemsSource is not changing. Once it changes and the first card is not shown, it crashes.
Any ideas? Many thanks

How can I put only English numbers in keyborard Xamarin.forms

My app has entry , when clicked it shows Numeric keyboard , the problem is if I put arabic numbers it doesn't calculate but close the app
is it possible to put only english number or how can I support arabic numbers ,
this is XAML file
<ContentPage.Content>
<AbsoluteLayout >
<!-- Text Box 1 -->
<StackLayout AbsoluteLayout.LayoutBounds="0.8,0.01" AbsoluteLayout.LayoutFlags="PositionProportional" >
<Label Text="" FontSize="Medium" FontAttributes="Bold" TextColor="Black" x:Name="lblname2" HorizontalOptions="Center" />
<Entry x:Name="Entnum2" WidthRequest="100" HeightRequest="40" BackgroundColor="White" Keyboard="Numeric" MaxLength="3" HorizontalTextAlignment="Center"
Focused="Entnum2_Focused" TextColor="Black" FontSize="Medium" PropertyChanged="Entnum2_PropertyChanged" />
</StackLayout>
<!-- Text Box 1 -->
<StackLayout AbsoluteLayout.LayoutBounds="0.2,0.01" AbsoluteLayout.LayoutFlags="PositionProportional">
<Label Text="" FontSize="Medium" FontAttributes="Bold" TextColor="Black" x:Name="lblname1" HorizontalOptions="Center" />
<Entry x:Name="Entnum1" WidthRequest="100" HeightRequest="40" BackgroundColor="White" Keyboard="Numeric" MaxLength="3" HorizontalTextAlignment="Center"
Focused="Entnum1_Focused" TextColor="Black" FontSize="Medium" />
</StackLayout>
<!-- view Editors -->
<Frame BackgroundColor="White" AbsoluteLayout.LayoutBounds="0.5,0.94,0.95,0.6" CornerRadius="15" AbsoluteLayout.LayoutFlags="All">
<ScrollView x:Name="scrollView" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--<Editor Text="0" FontAttributes="Bold" TextColor="Black" FontSize="Medium" WidthRequest="100" x:Name="num1" Grid.Column="0" HorizontalOptions="Center" IsReadOnly="True" />-->
<Label Text="" FontAttributes="Bold" TextColor="Black" FontSize="25" WidthRequest="100" x:Name="num1" Grid.Column="0" HorizontalOptions="Center" />
<Image Source="linev.png" Grid.Column="1" Opacity="0.3"/>
<Label Text="" FontAttributes="Bold" TextColor="Black" FontSize="25" WidthRequest="100" x:Name="num2" Grid.Column="2" HorizontalOptions="Center" />
</Grid>
</ScrollView>
</Frame>
<!-- view Buttons -->
<StackLayout Orientation="Horizontal" AbsoluteLayout.LayoutBounds="0.5,0.14,0.95,0.09" AbsoluteLayout.LayoutFlags="All" >
<Button TextColor="#1C84D3" Text="تراجع" x:Name="btnBack" Clicked="btnBack_Clicked" HorizontalOptions="CenterAndExpand" BackgroundColor="White" CornerRadius="15" HeightRequest="70"
WidthRequest="70" FontSize="20" />
<Button TextColor="#1C84D3" Text="سجل" Clicked="btnRegister_Clicked" HorizontalOptions="CenterAndExpand" BackgroundColor="White" FontSize="20" CornerRadius="15" HeightRequest="70"
WidthRequest="70" />
</StackLayout>
<controls:AdControlView AbsoluteLayout.LayoutBounds="0.5,0.26,0.95,0.14" AbsoluteLayout.LayoutFlags="All"
AdUnitId="{Static local:Constants.AdUnitIdTest}"/>
</AbsoluteLayout>
</ContentPage.Content>
This is the XAML.cs
int SUM1 = 0;
// SUM2 لتخزين النتيجة الثانية
int SUM2 = 0;
// DisplayPromptAsync تخزين حالة الاشعار
string action;
// لتبديل بين entrys
int tap = 1;
// عدد الاعبين
int playercount = 1;
int count = 0;
bool scroll = false;
public Blootrecord(bool newplay)
{
InitializeComponent();
if (newplay)
{
DisplayPrompt(lblname1, "اسم فريقهم");
DisplayPrompt(lblname2, "اسم فريقنا?");
}
else
{
// اذا مالنت الثيمة ب False هذا يعني انه يريد الرجوع لاخر لعية
// هذه اسطر لجلب اخر قيم تم تخزينها
lblname1.Text = Preferences.Get("lblname1", "");
lblname2.Text = Preferences.Get("lblname2", "");
num1.Text = Preferences.Get("num1", "");
num2.Text = Preferences.Get("num2", "");
SUM1 = Convert.ToInt32(Preferences.Get("SUM1", "0"));
SUM2 = Convert.ToInt32(Preferences.Get("SUM2", "0"));
count = Convert.ToInt32(Preferences.Get("count", "0"));
}
scrollView.HeightRequest = num1.HeightRequest;
}
/// <summary>
/// هذه دالة لعررض الاشعار
/// </summary>
/// <param name="label"></param>
/// /// <param name="label2"></param>
/// <param name="str"></param>
async void DisplayPrompt(Label label, string str)
{
var s = await DisplayPromptAsync("Alert", str);
if (string.IsNullOrEmpty(s))
label.Text = "فريق" + playercount++;
else
label.Text = s;
}
/// <summary>
/// زر سجل
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
///
private async void btnRegister_Clicked(object sender, EventArgs e)
{
try
{
scrollView.HeightRequest = num1.HeightRequest;
scroll = false;
// اضافة سط في Editors مع القيمه المدخله
num1.Text += "\n" + Entnum1.Text;
num2.Text += "\n" + Entnum2.Text;
//اذا كان الentry فارغ يبدل القيمه ب صفر
if (string.IsNullOrEmpty(Entnum1.Text))
{
num1.Text += "0";
}
if (string.IsNullOrEmpty(Entnum2.Text))
{
num2.Text += "0";
}
//تحويل القيمه الي عدد صحيح وجمعها ع اخر قميه
SUM1 += int.Parse(num1.Text.Substring(num1.Text.LastIndexOf("\n") + 1));
SUM2 += int.Parse(num2.Text.Substring(num2.Text.LastIndexOf("\n") + 1));
// اذا كانت القيمه اقل من 152 يتم اضافة سطر ثم خط ثم قيمه الجمع في كل Editor
if (SUM1 < 152 && SUM2 < 152)
{
num1.Text += "\n" + "------";
num2.Text += "\n" + "------";
num1.Text += "\n" + SUM1;
num2.Text += "\n" + SUM2;
}
else
{
// يتم عرض اكير قيمه مع اكبر فائز
if (SUM1 > SUM2)
{
action = await DisplayActionSheet(" هاردلك الفوز لهم " + SUM1 + " ", "اغلاق", "لعبة جديدة");
}
else if (SUM1 < SUM2)
{
action = await DisplayActionSheet(" مبروك الفوز لنا" + SUM2 + "", "اغلاق", "لعبة جديدة");
}
else
{
action = await DisplayActionSheet("تعادل", "اغلاق", "لعبة جديدة");
}
// اذا قمت بأختيار لعبة جديدة
if (action == "لعبة جديدة")
{
// يحذف جميع القيم ولاكن يبقي اسم العبين
num1.Text = num2.Text = "0";
Entnum1.Text = Entnum2.Text = null;
SUM1 = SUM2 = 0;
await scrollView.ScrollToAsync(num1, ScrollToPosition.Start, true);
count = 0;
scroll = true;
}
}
Entnum1.Text = Entnum2.Text = null;
// store data
// تخزين البيانات في كل مره
Preferences.Set("lblname1", lblname1.Text);
Preferences.Set("lblname2", lblname2.Text);
Preferences.Set("num1", num1.Text);
Preferences.Set("num2", num2.Text);
Preferences.Set("SUM1", SUM1.ToString());
Preferences.Set("SUM2", SUM2.ToString());
count++;
if (count >= 5 && count <= 7 && !scroll)
{
await scrollView.ScrollToAsync(num1, ScrollToPosition.Center, true);
}
else if (count > 7 && !scroll)
{
await scrollView.ScrollToAsync(num1, ScrollToPosition.End, true);
}
}
catch (Exception ex)
{
// في حالة وجود خطأ غير متوقع
await DisplayAlert("Opps!", ex.Message, "Ok");
await Navigation.PopAsync();
}
}
void btnBack_Clicked(System.Object sender, System.EventArgs e)
{
try
{
if (num1.Text != "0" && num2.Text != "0")
{
// يتم اذالة ثلاث اسطر وطرح قيمة السطر الثالث من المجموع الكلي ثم ازالة السطر الثالث
// editor number one
num1.Text = num1.Text.Remove(num1.Text.LastIndexOf("\n"));
num1.Text = num1.Text.Remove(num1.Text.LastIndexOf("\n"));
SUM1 -= int.Parse(num1.Text.Substring(num1.Text.LastIndexOf("\n") + 1));
num1.Text = num1.Text.Remove(num1.Text.LastIndexOf("\n"));
// editor number two
num2.Text = num2.Text.Remove(num2.Text.LastIndexOf("\n"));
num2.Text = num2.Text.Remove(num2.Text.LastIndexOf("\n"));
SUM2 -= int.Parse(num2.Text.Substring(num2.Text.LastIndexOf("\n") + 1));
num2.Text = num2.Text.Remove(num2.Text.LastIndexOf("\n"));
}
}
catch (Exception ex)
{
DisplayAlert("Opps!", ex.Message, "Ok");
}
}
private void Entnum1_Focused(object sender, FocusEventArgs e)
{
tap = 1;
}
private void Entnum2_Focused(object sender, FocusEventArgs e)
{
tap = 2;
}
private void Entnum2_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// في حالة اختيار Closr
if (action == "اغلاق")
{
// حزف جميع القيم المخزنه
Preferences.Clear();
// الرجوع الي الصفحة الاولة
Navigation.PopAsync();
}
}
}
}
This is an example of error , it calculates only English number
once I put Arabic Number it colses the app
Thank you
Arabic numbers are treated as char not numbers by the compiler if you want to use arabic number you have to manually map them with a case statement for example or a dictionary. if you parse them as an int an exception will be thrown.
problem fixed by this way
public int ArabicNumber (string unicode )
{
var str = unicode.Replace('\u0660', '0')
.Replace('0','0')
.Replace('\u0661', '1')
.Replace('\u0662', '2')
.Replace('\u0663', '3')
.Replace('\u0664', '4')
.Replace('\u0665', '5')
.Replace('\u0666', '6')
.Replace('\u0667', '7')
.Replace('\u0668', '8')
.Replace('\u0669', '9');
return int.Parse(str);
}

How can I make buttons wrap around like in a tag cloud with Xamarin Forms?

I have code like this:
<TableSection>
<ViewCell Height="200">
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
<Button Text="ABCDEFG"></Button>
</ViewCell>
</TableSection>
What I would like to do is to make the buttons look like a tag cloud and have the ViewCell height expand to accommodate them.
I didn't see any examples of how I could do this and would appreciate some feedback / suggestions.
Thanks
Update 1 - Here is what I tried but it doesn't work
<ViewCell Height="200">
<StackLayout Orientation="Horizontal" IsClippedToBounds="false" Spacing="5">
<Button Text="ABCDEF1" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF2" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF3" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF4" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF5" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF6" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF7" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
<Button Text="ABCDEF8" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
</Button>
</StackLayout>
</ViewCell>
Unfortunately all I see is the first four buttons and then nothing after that. What I was hoping to see was buttons on the first row and then on the second row another four buttons with the view cell expanding in height to fit.
You can achieve this following the guide provided by the xamarin forms developers site at https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/custom/
The problem you described is exactally what the sample code this guide shows. Creating a custom layout you can reuse this solution everywhere you need it.
Succinctly, what you have to do to create your WrapLayout:
Implement the methods to handle the children arrangemeant
Provide bindable properties to personalize the use on each need
Consume it as you wish
You may get results like this:
As Diego suggested , we can custom Layout to achieve the expect style.
Create new subclass which derives from Layout<View> , we just need to
Override OnMeasure to return the size of this layout .
Override LayoutChildren to determine positions and sizes of the children.
Create Bindable Properties to personalize the use on each need.
Custom Layout:
public class WrapLayout : Layout<View>
{
public static readonly BindableProperty SpacingProperty =
BindableProperty.Create
(
"Spacing",
typeof(double),
typeof(WrapLayout),
10.0,
propertyChanged: (bindable, oldvalue, newvalue) => ((WrapLayout)bindable).OnSizeChanged()
);
public double Spacing
{
get { return (double)GetValue(SpacingProperty); }
set { SetValue(SpacingProperty, value); }
}
private void OnSizeChanged()
{
this.ForceLayout();
}
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
if (WidthRequest > 0)
widthConstraint = Math.Min(widthConstraint, WidthRequest);
if (HeightRequest > 0)
heightConstraint = Math.Min(heightConstraint, HeightRequest);
double internalWidth = double.IsPositiveInfinity(widthConstraint) ? double.PositiveInfinity : Math.Max(0, widthConstraint);
double internalHeight = double.IsPositiveInfinity(heightConstraint) ? double.PositiveInfinity : Math.Max(0, heightConstraint);
return DoHorizontalMeasure(internalWidth, internalHeight);
}
private SizeRequest DoHorizontalMeasure(double widthConstraint, double heightConstraint)
{
int rowCount = 1;
double width = 0;
double height = 0;
double minWidth = 0;
double minHeight = 0;
double widthUsed = 0;
foreach (var item in Children)
{
var size = item.Measure(widthConstraint, heightConstraint);
height = Math.Max(height, size.Request.Height);
var newWidth = width + size.Request.Width + Spacing;
if (newWidth > widthConstraint)
{
rowCount++;
widthUsed = Math.Max(width, widthUsed);
width = size.Request.Width;
}
else
width = newWidth;
minHeight = Math.Max(minHeight, size.Minimum.Height);
minWidth = Math.Max(minWidth, size.Minimum.Width);
}
if (rowCount > 1)
{
width = Math.Max(width, widthUsed);
height = (height + Spacing) * rowCount - Spacing; // via MitchMilam
}
return new SizeRequest(new Size(width, height), new Size(minWidth, minHeight));
}
protected override void LayoutChildren(double x, double y, double width, double height)
{
double rowHeight = 0;
double yPos = y, xPos = x;
foreach (var child in Children.Where(c => c.IsVisible))
{
var request = child.Measure(width, height);
double childWidth = request.Request.Width;
double childHeight = request.Request.Height;
rowHeight = Math.Max(rowHeight, childHeight);
if (xPos + childWidth > width)
{
xPos = x;
yPos += rowHeight + Spacing;
rowHeight = 0;
}
var region = new Rectangle(xPos, yPos, childWidth, childHeight);
LayoutChildIntoBoundingRegion(child, region);
xPos += region.Width + Spacing;
}
}
}
In Xmal
<local:WrapLayout Spacing="5">
<Button Text="111111111111111" BackgroundColor="Red"/>
<Button Text="222" BackgroundColor="Green"/>
<Button Text="33333333333333333333333333" BackgroundColor="Gray"/>
<Button Text="444444" BackgroundColor="Blue"/>
<Button Text="5" BackgroundColor="Orange"/>
<Button Text="6666666666666666" BackgroundColor="Aqua"/>
<Button Text="77777777" BackgroundColor="Yellow"/>
<Button Text="888" BackgroundColor="Pink"/>
<Button Text="9 9 9 9" BackgroundColor="Purple"/>
<Button Text="10" BackgroundColor="Brown"/>
</local:WrapLayout>
Test
why not use a StackLayout ?
<StackLayout Orientation="Horizontal" IsClippedToBounds="false" Spacing="5" >
<Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30" ></Button>
<Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30" ></Button>
<Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30" ></Button>
<Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30" ></Button>
</StackLayout>

Xamarin Forms - Thread Efficiency

I am developing a Xamarin (PCL) cross platform app that i am currently testing on my Android Physical devices and Emulators. The app runs perfectly on the high-end phones, but "crashes unexpectedly" on the Samsung S4 and such low-end phones. It crashes only after i perform multiple activities and tasks.
I am assuming that has something to do with the task-thread-capacity of these phones. If i am right in that regard, how am i supposed to make my app such that it works smoothly and error free on all phones?
Edit - The error says "The app has closed unexpectedly". This error doesn't appear on a specific line because it has nothing to do with the code. It breaks only on certain "older" phones when many activities are performed. Example of activities include, Add data to database, updating/deleting them, moving from one activity to another, showing calendars and pie-charts from user entered data.
Edit 2 -Some of the Code that deals with images:
Xaml:
<ScrollView HorizontalOptions="Fill" Orientation="Horizontal">
<StackLayout Orientation="Vertical" BackgroundColor="GhostWhite" >
<StackLayout Orientation="Horizontal" BackgroundColor="GhostWhite" >
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="dairy" Image="{Binding Dairy_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="alcohol" Image="{Binding Alcohol_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="eggs" Image="{Binding Egg_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="fastfood" Image="{Binding Fastfood_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="fish" Image="{Binding Fish_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="fruit" Image="{Binding Fruit_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="grain" Image="{Binding Grain_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="legume" Image="{Binding Legume_Image}"/>
</StackLayout>
<StackLayout Orientation="Horizontal" BackgroundColor="GhostWhite" >
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="meat" Image="{Binding Meat_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="munchies" Image="{Binding Munchies_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="nuts" Image="{Binding Nut_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="potato" Image="{Binding Potato_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="soda" Image="{Binding Soda_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="sweets" Image="{Binding Sweet_Image}"/>
<Button HeightRequest="50" BackgroundColor="GhostWhite" WidthRequest="50" Command="{Binding Button_Clicked_Food}" CommandParameter="vegetables" Image="{Binding Vegetable_Image}"/>
</StackLayout>
</StackLayout>
.CS:
public UserMealINC_vm(User_Profiles up, DateTime day)
{
try
{
Day = day;
User_pro = up;
Bool_Food_Type = false;
Food_Name = "";
Type = "";
Food_Weight = "0";
Selected_Food = new List<string>();
//All meal item are first initialized with the non-coloured images
Dairy_Image = "drawable/dairy.png";
Alcohol_Image = "drawable/alcohol.png";
Egg_Image = "drawable/eggs.png";
Fastfood_Image = "drawable/fastfood.png";
Fish_Image = "drawable/fish.png";
Fruit_Image = "drawable/fruit.png";
Grain_Image = "drawable/grain.png";
Legume_Image = "drawable/legume.png";
Meat_Image = "drawable/meat.png";
Munchies_Image = "drawable/munchies.png";
Nut_Image = "drawable/nuts.png";
Potato_Image = "drawable/potato.png";
Soda_Image = "drawable/soda.png";
Sweet_Image = "drawable/sweets.png";
Vegetable_Image = "drawable/vegetables.png";
this.Button_Clicked_Food = new Command<string>((key) =>
{
//Change the item selected from color to non-color, or vice-versa
if (Selected_Food.Contains(key))
{
if (key == "dairy")
{
Dairy_Image = "drawable/dairy.png";
}
else if (key == "alcohol")
{
Alcohol_Image = "drawable/alcohol.png";
}
else if (key == "eggs")
{
Egg_Image = "drawable/eggs.png";
}
else if (key == "fastfood")
{
Fastfood_Image = "drawable/fastfood.png";
}
else if (key == "fish")
{
Fish_Image = "drawable/fish.png";
}
else if (key == "fruit")
{
Fruit_Image = "drawable/fruit.png";
}
else if (key == "grain")
{
Grain_Image = "drawable/grain.png";
}
else if (key == "legume")
{
Legume_Image = "drawable/legume.png";
}
else if (key == "meat")
{
Meat_Image = "drawable/meat.png";
}
else if (key == "munchies")
{
Munchies_Image = "drawable/munchies.png";
}
else if (key == "nuts")
{
Nut_Image = "drawable/nuts.png";
}
else if (key == "potato")
{
Potato_Image = "drawable/potato.png";
}
else if (key == "soda")
{
Soda_Image = "drawable/soda.png";
}
else if (key == "sweets")
{
Sweet_Image = "drawable/sweets.png";
}
else if (key == "vegetables")
{
Vegetable_Image = "drawable/vegetables.png";
}
else
{
//Key out of bounds???
}
Selected_Food.Remove(key);
}
else
{
if (key == "dairy")
{
Dairy_Image = "drawable/dairy_color.png";
}
else if (key == "alcohol")
{
Alcohol_Image = "drawable/alcohol_color.png";
}
else if (key == "eggs")
{
Egg_Image = "drawable/eggs_color.png";
}
else if (key == "fastfood")
{
Fastfood_Image = "drawable/fastfood_color.png";
}
else if (key == "fish")
{
Fish_Image = "drawable/fish_color.png";
}
else if (key == "fruit")
{
Fruit_Image = "drawable/fruit_color.png";
}
else if (key == "grain")
{
Grain_Image = "drawable/grain_color.png";
}
else if (key == "legume")
{
Legume_Image = "drawable/legume_color.png";
}
else if (key == "meat")
{
Meat_Image = "drawable/meat_color.png";
}
else if (key == "munchies")
{
Munchies_Image = "drawable/munchies_color.png";
}
else if (key == "nuts")
{
Nut_Image = "drawable/nuts_color.png";
}
else if (key == "potato")
{
Potato_Image = "drawable/potato_color.png";
}
else if (key == "soda")
{
Soda_Image = "drawable/soda_color.png";
}
else if (key == "sweets")
{
Sweet_Image = "drawable/sweets_color.png";
}
else if (key == "vegetables")
{
Vegetable_Image = "drawable/vegetables_color.png";
}
else
{
//Key out of bounds???
}
Selected_Food.Add(key);
}
});
}
catch (Exception ex)
{
App.Current.MainPage.DisplayAlert("UserMealINC_vm 1!", ex.Message, "OK");
}
}
It turns out that the device memory was getting overflowed by all the multiple images i had in my App. (As suggested by #hvaughan3)
This link has the answer to it.
You basically just have to add these two lines in you Android Manifest (Under Application) -
android:hardwareAccelerated="false"
android:largeHeap="true"

How to check the check box dynamically in listbox in windows phone 7?

I have the listbox with four checkbox items. If I give the input as 2 then first two check boxes should select,this should happen programatically.
Please help me out..
Thanks,
.xaml page
<StackPanel Background="White" Margin="5,0,5,0">
<ListBox x:Name="listBox2" Foreground="Black" Height="300" SelectionMode="Multiple" SelectionChanged="listBox2_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Name="stackpanel1" Orientation="Horizontal" >
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Name}" Foreground="Black" Height="68" Margin="0,-15,0,-10" BorderThickness="0" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked">
</CheckBox>
</StackPanel>
<Rectangle Fill="Gray" Height=".5" HorizontalAlignment="Stretch" Width="440" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
.cs code:
List<Items> source = new List<Items>();
source.Add(new Items() { Name = "Item 1" });
source.Add(new Items() { Name = "Item 2" });
source.Add(new Items() { Name = "Item 3" });
source.Add(new Items() { Name = "Item 4" });
source.Add(new Items() { Name = "Item 5" });
source.Add(new Items() { Name = "Item 6" });
`` listBox2.ItemsSource = source;
Items class
public class Items
{
public string Name
{
get;
set;
}
}
Here's a really crude way of doing what I think you've described. It doesn't use much of your code directly but should get you moving in the right direction.
XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<toolkit:ListPicker SelectionChanged="ListPicker_OnSelectionChanged">
<toolkit:ListPickerItem>0</toolkit:ListPickerItem>
<toolkit:ListPickerItem>1</toolkit:ListPickerItem>
<toolkit:ListPickerItem>2</toolkit:ListPickerItem>
<toolkit:ListPickerItem>3</toolkit:ListPickerItem>
<toolkit:ListPickerItem>4</toolkit:ListPickerItem>
</toolkit:ListPicker>
<ItemsControl x:Name="TheListBox" Grid.Row="1" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Note that I'm using the Windows Phone Toolkit (get it from http://phone.codeplex.com/ or nuget)
C#
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
public partial class MainPage : PhoneApplicationPage
{
ObservableCollection<Items> source = new ObservableCollection<Items>();
public MainPage()
{
InitializeComponent();
source.Add(new Items { Id = 1 });
source.Add(new Items { Id = 2 });
source.Add(new Items { Id = 3 });
source.Add(new Items { Id = 4 });
TheListBox.ItemsSource = source;
}
private void ListPicker_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (source.Count > 0 && e.AddedItems.Count > 0)
{
for (int i = 0; i < source.Count; i++)
{
this.source[i].IsChecked = int.Parse(((ContentControl)(e.AddedItems[0])).Content.ToString()) >= this.source[i].Id;
}
}
}
}
public class Items : INotifyPropertyChanged
{
private bool isChecked;
public int Id { get; set; }
public string Name
{
get
{
return "Item " + this.Id;
}
}
public bool IsChecked
{
get
{
return this.isChecked;
}
set
{
this.isChecked = value;
this.OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Resources