I use syncfusion listview to create listview on xamarin forms
I want to use the ItemAppearing option in listview
I used this EXAMPLE on website:https://help.syncfusion.com/cr/cref_files/xamarin/Syncfusion.SfListView.XForms~Syncfusion.ListView.XForms.SfListView.html
and this EXAMPLE: https://help.syncfusion.com/cr/cref_files/xamarin/Syncfusion.SfListView.XForms~Syncfusion.ListView.XForms.SfListView~ItemAppearing_EV.html#ExampleBookmark
I use this example and found this problem
ListView.ItemAppearing +=listView_ItemAppearing;
public void listView_ItemAppearing(object sender, Syncfusion.ListView.XForms.ItemAppearingEventArgs e)
{
var temp= e.ItemData as IEnumerable<ListViewCall>;
//temp.ToList();
}
I cast e.ItemData to List<ListViewCall> and get null
e.ItemData has data but var temp is null
Why would this be?
ItemData :Gets the underlying data object of the ListViewItem when item appearing from the bound data source.
so e.ItemData will return you the binding object. like the example above,it will return the object BookInfo.
public void listView_ItemAppearing(object sender, Syncfusion.ListView.XForms.ItemAppearingEventArgs e)
{
var temp= e.ItemData as BookInfo;
}
public void listView_ItemAppearing(object sender, Syncfusion.ListView.XForms.ItemAppearingEventArgs e)
{
if (e.ItemData is GroupResult)
{
var listViewCalls = (e.ItemData as GroupResult).Items as EnumerableQuery<ListViewCall>;
foreach (var listViewCall in listViewCalls)
{
}
}
else if (e.ItemData is ListViewCall)
{
var listViewCall = e.ItemData as ListViewCall;
}
// foreach (Object obj in e.ItemData.GetType().GetProperties(System.Reflection.BindingFlags.Public | BindingFlags.Instance))
// {
// string s = (obj as Call).Title;
//}
}
Related
I am trying to Implement AutocompleteTextview in xamarin forms,
till now i have achieved the customisation and look which i need to for my Auto Complete Bar,
but the thing where i am stuck is filling of data to Dataadapter from Shared Library also i am not getting what text is selected inside the Entry bar, so could anyone help me how can i bind my list from pcl to native and also i need two way data to Text Property
here is the code which i had implemented till now
my common class
public class AutoCompleteViewv3 : View
{
public AutoCompleteViewv3()
{
}
}
My Android Implementation
[assembly: ExportRenderer(typeof(AutoSuggestBox),
typeof(AutoCompleteViewRendererv3))]
namespace PredictiveList.Droid
{
public class AutoCompleteViewRendererv3 :
ViewRenderer<AutoCompleteViewv3,
AutoCompleteTextView>
{
static string[] COUNTRIES = new string[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", };
public AutoCompleteViewRendererv3(Android.Content.Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<AutoCompleteViewv3> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
AutoCompleteTextView textView = (AutoCompleteTextView)LayoutInflater.From(Context).Inflate(Resource.Layout.TextEditorLayouts, null);
var adapter = new ArrayAdapter<String>(Context,
Resource.Layout.list_item, COUNTRIES);
textView.Adapter = adapter;
SetNativeControl(textView);
}
// Use the control here.
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
// variable this.Control is the AutoCompleteTextView, so you an manipulate it.
}
}
}
For Ios i am still trying to implemented
please check Code here for Auto complete
My borderless custom renderer for picker
public class BorderlessPickerRenderer : PickerRenderer
{
public static void Init() { }
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = null;
}
}
}
It will change the picker list text color as white. please see the screenshot
If you check the source code of PickerRenderer, you will find that the Dialog is totally generated in the code behind.
So here to set a Transparent(border-less) background, we can re-write the Click event of this control, for example:
public class BorderlessPickerRenderer : Xamarin.Forms.Platform.Android.PickerRenderer
{
private IElementController ElementController => Element as IElementController;
private AlertDialog _dialog;
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.NewElement == null || e.OldElement != null)
return;
Control.Click += Control_Click;
}
protected override void Dispose(bool disposing)
{
Control.Click -= Control_Click;
base.Dispose(disposing);
}
private void Control_Click(object sender, EventArgs e)
{
Picker model = Element;
var picker = new NumberPicker(Context);
if (model.Items != null && model.Items.Any())
{
picker.MaxValue = model.Items.Count - 1;
picker.MinValue = 0;
picker.SetDisplayedValues(model.Items.ToArray());
picker.WrapSelectorWheel = false;
picker.DescendantFocusability = DescendantFocusability.BlockDescendants;
picker.Value = model.SelectedIndex;
}
var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
layout.AddView(picker);
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetNegativeButton(global::Android.Resource.String.Cancel, (s, a) =>
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
// It is possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
_dialog = null;
});
builder.SetPositiveButton(global::Android.Resource.String.Ok, (s, a) =>
{
ElementController.SetValueFromRenderer(Picker.SelectedIndexProperty, picker.Value);
// It is possible for the Content of the Page to be changed on SelectedIndexChanged.
// In this case, the Element & Control will no longer exist.
if (Element != null)
{
if (model.Items.Count > 0 && Element.SelectedIndex >= 0)
Control.Text = model.Items[Element.SelectedIndex];
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
// It is also possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
}
_dialog = null;
});
_dialog = builder.Create();
_dialog.DismissEvent += (ssender, args) =>
{
ElementController?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
};
_dialog.Show();
_dialog.Window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));
}
}
Rendering image of this custom picker:
The font color and button's style can be modified as you need since you created this dialog by yourself. And the style of the dialog also depends on the style of your app.
I am trying to write a custom renderer for a Xamarin Map on UWP and a collection change event in the PCL is not triggering the appropriate event in the UWP custom renderer. It works just fine on iOS and Android.
With the following code the event ItemsCollectionChanged never gets called in the CustomMapRenderer even through the OnItemsSourcePropertyChanged is being called every 5 seconds.
public class CustomMap : Map
{
#region << Events >>
public event EventHandler ItemsCollectionChanged;
#endregion
private static void OnItemsSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var map = bindable as CustomMap;
if (map == null)
return;
map.ItemsSource.CollectionChanged += (s, e) =>
{
SetPin(bindable);
if (map.ItemsCollectionChanged != null)
{
map.ItemsCollectionChanged(bindable, new EventArgs());
}
};
}
}
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
Namespace MyNamespace.Renderers
{
public class CustomMapRenderer : MapRenderer
{
MapControl _nativeMap;
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
_nativeMap.MapElementClick -= OnMapElementClick;
_nativeMap.Children.Clear();
_nativeMap = null;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
formsMap.ItemsCollectionChanged += ItemsCollectionChanged;
_pinClickedCommand = formsMap.PinClickedCommand;
_routeCoordinates = formsMap.ItemsSource;
_nativeMap = Control as MapControl;
_nativeMap.Children.Clear();
_nativeMap.MapElementClick += OnMapElementClick;
var snPosition = new BasicGeoposition { Latitude = 45, Longitude = -88 };
Geopoint snPoint = new Geopoint(snPosition);
var mapIcon = new MapIcon();
if (mapIcon != null)
{
_nativeMap.MapElements.Remove(mapIcon);
}
mapIcon.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
mapIcon.Location = snPoint;
mapIcon.NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 1.0);
_nativeMap.MapElements.Add(mapIcon);
_nativeMap.Center = snPoint;
}
}
void ItemsCollectionChanged(object sender, EventArgs e)
{
;
}
}
}
I used a singleton to get the observable collection that I needed
How can I make the pin to display label by default (without clicking it) when it is added to the map in Xamarin.Forms.
map.MoveToRegion(MapSpan.FromCenterAndRadius(position, Distance.FromMiles(0.4)));
var pin = new Pin
{
Type = PinType.Place,
Position = position,
Label = "Some Text",
};
map.Pins.Add(pin);
You can do it via a custom map render.
As an example, on iOS you can add two delegates to the MKMapView control:
DidAddAnnotationViews: Any time a MKAnnotation is added, pre-select them all..
DidDeselectAnnotationView: If someone/something tries to deselect the MKAnnotation, just re-select them all...
Working Example as a starting point:
[assembly: ExportRenderer(typeof(PinViewMap), typeof(PinViewMapRenderer))]
namespace WorkingWithMaps.iOS
{
public class PinViewMapRenderer : MapRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control != null)
{
var map = Control as MKMapView;
map.DidDeselectAnnotationView += (object sender, MKAnnotationViewEventArgs eventArgs) =>
{
foreach (var anno in ((MKMapView)sender).Annotations)
{
((MKMapView)sender).SelectAnnotation(anno, true);
}
};
map.DidAddAnnotationViews += (object sender, MKMapViewAnnotationEventArgs eventArgs) =>
{
foreach (var anno in ((MKMapView)sender).Annotations)
{
((MKMapView)sender).SelectAnnotation(anno, true);
}
};
}
}
}
}
Basically i am trying to pull the contacts from the phone and showing them in the Listpicker control for a feature in my app. I have two Listpickers, one for name of contacts list and the other showing the list of phonenumbers for the chosen contact.
Here is my code:
//Declarations
ContactsSearchEventArgs e1;
String SelectedName;
String SelectedNumber;
List<string> contacts = new List<string>();
List<string> phnum = new List<string>();
public AddressBook() // Constructor
{
InitializeComponent();
Contacts contacts = new Contacts();
contacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
contacts.SearchAsync(string.Empty,FilterKind.None,null);
}
void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
e1 = e;
foreach (var result in e.Results)
{
if (result.PhoneNumbers.Count() != 0)
{
contacts.Add(result.DisplayName.ToString());
}
}
Namelist.ItemsSource = contacts;
}
private void Namelist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedName = (sender as ListPicker).SelectedItem.ToString();
phnum.Clear();
foreach (var result in e1.Results)
{
if (SelectedName == result.DisplayName)
{
phnum.Add(result.PhoneNumbers.FirstOrDefault().ToString());
}
}
Numbers.ItemsSource = phnum;
}
private void Numbers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedNumber = (sender as ListPicker).SelectedItem.ToString();
}
Am able to populate the Numberlist with phonenumbers for the chosen name at the Listpicker background, but the number is not showing up in the front. I think Numbers_SelectionChanged() event is called only one time when the page loads and am not seeing it triggerd when i change the contact list. Anyone has an idea of where am going wrong ?
If you change
List<string>
To
ObservableCollection<string>
this should work.
Also then you only need to set the ItemSource once, in Xaml or you constructor.
But you may run into another issue with the November 2011 Toolkit and ListPicker.
See more in thread.
private void Namelist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedName = (sender as ListPicker).SelectedItem.ToString();
phnum = new List<string>(); // Changed instead of phnum.Clear()
foreach (var result in e1.Results)
{
if (SelectedName == result.DisplayName)
{
phnum.Add(result.PhoneNumbers.FirstOrDefault().ToString());
}
}
Numbers.ItemsSource = phnum;
}
This works !!. While debugging i found its phnum.Clear() giving a problem. So i thought to create a new instance of phnum list for selected contact.