To Use Telerik RadDataPager in Silverlight (Issue After Rebinding data) - xaml

I am using MVVM framework. My question is that i am binding PagedCollectionView to radgridview and using raddatapager i want to do paging. As i am new to this can anybody tell me where i am going wrong. Also there is one problem while fetching record this works fine for 800 records but it didn't work for records above 1000(web service code is attached).
In Web service i am using this function to get list:
public List<GetStudents> GetStudentsListForUpdate(int schoolId, int academicYearId)
{
return new DbHelper().Find(StudentAdmissionCommands.GetStudentsListForUpdate(schoolId, academicYearId), new GenericObjectBuilder<GetStudents>());
}
![It works first time when page is loaded as snapshot is attached][1]
In ViewModel I defined Pagedcollection view like this:
PagedCollectionView pcv;
public PagedCollectionView Pcv
{
get { return pcv; }
set { pcv = value; OnPropertyChanged("Pcv"); }
}
//This function written to get student's list
public void GetStud()
{
Studlist.Clear();
RootVisualHelper.SetBusy(true);
StudentAdmissionServiceClient client = new StudentAdmissionServiceClient();
client.GetStudentsListForUpdateCompleted += (Cs, Ea) =>
{
if (Ea.Error == null)
{
RootVisualHelper.SetBusy(false);
if (Ea.Result.ToList().Count == 0)
{
EmptyMessageVisibility = "Visible";
}
else
{
EmptyMessageVisibility = "Collapsed";
foreach (var item in Ea.Result)
{
Studlist.Add(item);
}
Pcv = new PagedCollectionView(Studlist);
Pcv.GroupDescriptions.Clear();
Pcv.GroupDescriptions.Add(new PropertyGroupDescription("AllocatedClass"));
}
}
};
client.GetStudentsListForUpdateAsync(SchoolIdLog, AcademicYearId);
}
In Xaml, RadGridView binding:
<telerik:RadGridView ItemsSource="{Binding Pcv}" SelectedItem="{Binding SelectedStudentList,Mode=TwoWay}"
telerik:StyleManager.Theme="{Binding Theme,Mode=TwoWay}"
helpers:CustomFilterBehavior.TextBox="{Binding ElementName=textBoxFilterValue}"
ShowColumnFooters="True" ShowGroupPanel="False"
AutoGenerateColumns="False" IsReadOnly="True" Grid.Row="3"
Grid.ColumnSpan="2" x:Name="RadGridView1"
CanUserFreezeColumns="False" GroupRenderMode="Flat"
RowIndicatorVisibility="Collapsed">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="RowActivated">
<shared:EventToCommandTrigger Command="{Binding UpdateStudentCommand}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding StudentRollNo}" Header="Student Code" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding StudentRegNo}" Header="Reg No." />
<telerik:GridViewDataColumn DataMemberBinding="{Binding StudentEsisNo}" Header="Esis No." />
<telerik:GridViewDataColumn DataMemberBinding="{Binding StudentName}" Header="Student Name" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding UserName}" Header="User Name" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding AllocatedClass}" Header="Class" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding Gender}" Header="Gender" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding DateOfBirth,StringFormat=dd/MM/yyyy}"
Header="Date Of Birth" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding ParentName}" Header="Parent Name" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding ParentMobile}" Header="Father Mob. No." />
<telerik:GridViewDataColumn DataMemberBinding="{Binding MotherMobile1}" Header="Mother Mob. No." />
<telerik:GridViewDataColumn DataMemberBinding="{Binding StudentType}" Header="Student Type" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
<telerik:RadDataPager PageSize="100" Grid.Row="4"
FontSize="12" Margin="0,-1,0,0"
Source="{Binding Items, ElementName=RadGridView1}"
IsTotalItemCountFixed="false"
DisplayMode="FirstLastPreviousNextNumeric, Text" />
Whether I have to handle events of pagedcollection view? If so how to handle in MVVM Pattern?

Related

adjust and move the content of a page up slightly when the keyboard appears in an Entry control Xamarin Forms

I have a registration form, when the user is entering data such as Email, below that Entry control there is a Label that appears if there is an error in the input. So my problem is that the virtual keyboard hides the Label showing input errors and I don't want that to happen.
With keyboard.jpg without keyboard.jpg
It will be that there will be some way to move the content of the form a little higher so that the Control Entry can be seen along with the Error Label
<StackLayout>
<Entry
Keyboard="Email"
MaxLength="30"
Placeholder="Enter Email"
ReturnType="Next"
Style="{StaticResource BorderlessEntryStyle}"
Text="{Binding Email.Value}">
<Entry.Behaviors>
<behaviorsValidate:EventToCommandBehavior Command="{Binding ValidateEmailCommand}" EventName="TextChanged" />
</Entry.Behaviors>
</Entry>
<Label
Margin="4,-4,0,0"
FontSize="12"
IsVisible="{Binding Email.IsValid, Converter={StaticResource InverseBoolConverter}}"
Style="{StaticResource SimpleLabelStyle}"
Text="{Binding Email.Errors, Converter={StaticResource FirstValidationErrorConverter}}"
TextColor="{DynamicResource Red}"
VerticalOptions="FillAndExpand" />
</StackLayout>
About adjusting elements when keyboard shows in Xamarin Forms, find one way to do this.
On android you just need to add your elements inside a Grid and use the platform specific UseWindowSoftInputModeAdjust Resize in the Application XAML.
firstly, create a new class that extend from Grid in Shared code.
public class KeyboardView: Grid
{
}
Then adding your control inside it.
<views:KeyboardView Padding="0,60,0,0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="60" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Source="ic_test"
HeightRequest="80"
WidthRequest="80"
HorizontalOptions="CenterAndExpand"
Grid.Row="0"/>
<Label Text="Login"
FontAttributes="Bold"
TextColor="CornflowerBlue"
HorizontalOptions="CenterAndExpand"
FontSize="25"
VerticalOptions="Center"
Margin="0,20,0,0"
Grid.Row="1"
x:Name="welcomeText"/>
<Entry Placeholder="Email"
Grid.Row="2"
Margin="20,0"
x:Name="email"
ReturnType="Done"
Keyboard="Email"/>
<Entry Placeholder="Password"
Margin="20,0"
Grid.Row="3"
HeightRequest="50"
x:Name="password"
ReturnType="Done"
IsPassword="true"/>
<Button VerticalOptions="EndAndExpand"
BackgroundColor="CornflowerBlue"
HeightRequest="60"
TextColor="White"
CornerRadius="0"
Grid.Row="4"
Text="Login"/>
</views:KeyboardView>
Thirdly, add platform specific UseWindowSoftInputModeAdjust with Resize value on the Application XAML
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="KeyboardSample.App"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:Application.WindowSoftInputModeAdjust="Resize">
On iOS we have to create a custom renderer to do the resize. Don't test on ios device.
[assembly: ExportRenderer(typeof(KeyboardView), typeof(KeyboardViewRenderer))]
namespace KeyboardSample.iOS.Renderers
{
public class KeyboardViewRenderer : ViewRenderer
{
NSObject _keyboardShowObserver;
NSObject _keyboardHideObserver;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
RegisterForKeyboardNotifications();
}
if (e.OldElement != null)
{
UnregisterForKeyboardNotifications();
}
}
void RegisterForKeyboardNotifications()
{
if (_keyboardShowObserver == null)
_keyboardShowObserver = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardShow);
if (_keyboardHideObserver == null)
_keyboardHideObserver = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardHide);
}
void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
{
NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
CGSize keyboardSize = result.RectangleFValue.Size;
if (Element != null)
{
Element.Margin = new Thickness(0, 0, 0, keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
}
}
void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
{
if (Element != null)
{
Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
}
}
void UnregisterForKeyboardNotifications()
{
if (_keyboardShowObserver != null)
{
_keyboardShowObserver.Dispose();
_keyboardShowObserver = null;
}
if (_keyboardHideObserver != null)
{
_keyboardHideObserver.Dispose();
_keyboardHideObserver = null;
}
}
}
}

How to bind the data from code inside XAML

I have this class:
public partial class Calendar : ContentPage, INotifyPropertyChanged
{
public ICommand EventSelectedCommand => new Command(async (item) => await ExecuteEventSelectedCommand(item));
public ICommand DayTappedCommand => new Command<DateTime>(async (date) => await DayTapped(date));
public EventCollection Events { get; set; }
private void SetCalendar()
{
Events = new EventCollection
{
[DateTime.Now] = new List<EventModel>
{
new EventModel { Name = "Herrenabend, 10:00 - 12:00 – 5000 Scanns", ID = 100},
};
}
and I wanna do bind the data to my calendar.
I tried this:
<Grid Grid.Row="1" Grid.Column="1">
<controls:Calendar
x:Name="calender"
DayTappedCommand="{Binding DayTappedCommand}"
Events="{Binding Q2go.MainMenu_Partners.Calendar.Events}">
<controls:Calendar.EventTemplate>
<DataTemplate>
<StackLayout>
<Label
Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Medium" >
<Label.GestureRecognizers>
<TapGestureRecognizer
Tapped="ClickOnLabel"
/>
</Label.GestureRecognizers>
</Label>
<Label
Grid.Row="1"
Text="{Binding ID}"
FontSize="8" >
<Label.GestureRecognizers>
<TapGestureRecognizer
Tapped="ClickOnLabel"
/>
</Label.GestureRecognizers>
</Label>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding BindingContext.EventSelectedCommand, Source={x:Reference test}}"
CommandParameter="{Binding .}" />
</StackLayout.GestureRecognizers>
</StackLayout>
</DataTemplate>
</controls:Calendar.EventTemplate>
</controls:Calendar>
</Grid>
But the data isn't given into the calendar and non of the events fire.
Where is the missing link here?
I thought by: Events="{Binding Q2go.MainMenu_Partners.Calendar.Events}">
I am doing everything correctly. but nothing is displayed. Why is that?
I know that if I just give the data to the calendar inside code (calender.events = events) it works just fine (still no event handlers) but i want it to bind the data from code. So without this line (calender.events = events).
I read in every sample that this should work, but it doesn't for me. So where is the issue?
if your page's BindingContext is set to this then you should just use Events="{Binding Events}" as the Binding expression

Using method from another class in Xamarin

I am using Xamarin Cross Platform and Windows 10.
Trying to add behavior on entry. Had class Behaviors:
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace CoTraveller
{
public class Behaviors
{
public class NumericValidationBehavior : Behavior<Entry>
{
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += OnEntryTextChanged;
base.OnAttachedTo(entry);
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= OnEntryTextChanged;
base.OnDetachingFrom(entry);
}
public void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
double result;
bool isValid = double.TryParse(args.NewTextValue, out result);
((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
}
}
}
}
Xaml page where I want to use this class method:
<?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:local="clr-namespace:CoTraveller"
x:Class="CoTraveller.RegistrationPage">
<ContentPage.Content>
<ScrollView>
<StackLayout VerticalOptions="CenterAndExpand" Padding="5">
<StackLayout Orientation="Horizontal">
<Entry x:Name="name_entry" Placeholder="First Name">
<Entry.Behaviors>
<local:NumericValidationBehavior />
</Entry.Behaviors>
</Entry>
<Entry x:Name="surname_entry" Placeholder="Surname"></Entry>
</StackLayout>
<Entry Placeholder="Login"></Entry>
<StackLayout Orientation="Horizontal">
<Entry x:Name="pass_entry" Placeholder="Password" IsPassword="True"></Entry>
<Entry x:Name="pass_confirm_entry" Placeholder="Confirm Password" IsPassword="True"></Entry>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Save Password"></Label>
<Switch IsToggled="False"></Switch>
</StackLayout>
<Label Text="Date Of Birth"></Label>
<DatePicker x:Name="birthday_dp"></DatePicker>
<Picker x:Name="sex_p" HorizontalOptions="FillAndExpand" Title="Click and select gender">
<Picker.Items>
<x:String>Male</x:String>
<x:String>Female</x:String>
</Picker.Items>
</Picker>
<Entry Placeholder="Email (optional)"></Entry>
<Entry Placeholder="Phone number (optional)"></Entry>
<Picker x:Name="type_entry" HorizontalOptions="FillAndExpand" Title="Click and select user type">
<Picker.Items>
<x:String>Driver</x:String>
<x:String>Pedestrian</x:String>
</Picker.Items>
</Picker>
<Button Text="Sign Up" Clicked="SignUpBtn"></Button>
<Label x:Name="sign_in_lbl" Text="Already have account? Sign In" TextColor="Blue"></Label>
</StackLayout>
</ScrollView>
</ContentPage.Content> </ContentPage>
Both are in the same namespace and CoTraveller is the name of my project.
I had errors like:
Severity Code Description Project File Line Suppression State
Error Position 12:30. Type local:NumericValidationBehavior not found in xmlns clr-namespace:CoTraveller CoTraveller D:\CoTraveller\CoTraveller\CoTraveller\RegistrationPage.xaml 12
Severity Code Description Project File Line Suppression State
Error XLS0414 The type 'local:NumericValidationBehavior' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built. CoTraveller RegistrationPage.xaml 12
What is the reason? I declared namespace in XAML file, but smth is wrong...
The namespace declaration xmlns:local="clr-namespace:CoTraveller" is correct, but because the behavior is a nested type, you need to qualify the name with the outer type where you use it. Use <local:Behaviors.NumericValidationBehavior />.

Hide column or row when content is not visible

I have an XAML Grid with columns and I would like to hide or collapse the column when the content is not visible.
Example:
I have this layout:
<Grid >
<Button Grid.Column="0" x:Name="FirstButton" Text="First button" />
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
When FirstButton is not visible I want this result
<Grid >
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
Answering myself :
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=IsVisible, Converter={StaticResource IsVisibleToGridLength}" BindingContext="{x:Reference FirstButton}" />
<ColumnDefinition Width="{Binding Path=IsVisible, Converter={StaticResource IsVisibleToGridLength}" BindingContext="{x:Reference SecondButton}" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="FirstButton" Text="First button" />
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
And for the converter part
class IsVisibleToGridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo language)
{
try
{
GridUnitType t = GridUnitType.Star;
if (parameter != null)
{
Enum.TryParse<GridUnitType>((string)parameter, true, out t);
}
if (value != null)
{
bool d = (bool)value;
return d == false ? new GridLength(0,GridUnitType.Absolute) : new GridLength(1, t);
}
return null;
}
catch (Exception exp)
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
{
return null;
}
}
And Obviously the App.xml part
<Application x:Class="MyNameSpace.App"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:class="clr-namespace:MyNameSpace.Class;assembly=MyNameSpace"/>
<Application.Resources>
<ResourceDictionary>
<class:IsVisibleToGridLengthConverter x:Key="IsVisibleToGridLength"/>
</ResourceDictionary>
</Application.Resources>
</Application>
Hope it helps !!

How to add row in MVVM pattern?

Say I use xaml to create a telerik RadGridView.
<telerik:RadGridView x:Name="myRadGridView"
Width="1000"
IsReadOnly="True"
ValidatesOnDataErrors="None"
AutoGenerateColumns="False"
IsFilteringAllowed="False"
ShowGroupPanel="False"
ShowColumnFooters="False"
CanUserResizeColumns="False"
CanUserFreezeColumns="False"
SelectionMode="Single"
CanUserReorderColumns="False"
CanUserSortColumns="False"
CanUserInsertRows="False"
CanUserDeleteRows="False"
CanUserSelect="True"
RowIndicatorVisibility="Visible"
Height="250"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ItemsSource="{Binding Information}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectionChanged="myRadGridView_SelectionChanged"
>
<telerik:RadGridView.Columns>
<telerik:GridViewColumn />
<telerik:GridViewColumn />
.....
</telerik:RadGridView.Columns>
There are many columns.
I get the data from my ViewModel. Now I want to add a new row to get the total value of the above rows.
My question is that how to add the row in my ViewModel?
Try this:
With this you can do it for specific columns via XAML (no need other code)
<telerik:GridViewDataColumn Header="Quantity"
DataMemberBinding="{Binding ProdQuantity}"
UniqueName="Quantity">
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:SumFunction Caption="Sum: " />
</telerik:GridViewDataColumn.AggregateFunctions>
</telerik:GridViewDataColumn>
OR For all numeric columns
<telerik:RadGridView x:Name="myRadGridView"
Width="1000"
IsReadOnly="True"
...
ShowColumnFooters="True"
AutoGeneratingColumn="GridView_AutoGeneratingColumn"
ItemsSource="{Binding Information}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectionChanged="myRadGridView_SelectionChanged"
>
In code:
private void GridView_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
{
if(!e.Column is GridViewDataColumn)
return;
GridViewDataColumn col = (e.Column as GridViewDataColumn);
if (col.DataType != null)
{
if (col.DataType == typeof(Int32) || col.DataType == typeof(long) || col.DataType == typeof(Double))
e.Column.AggregateFunctions.Add(new SumFunction());
}
}
note that columns must be GridViewDataColumn