I have a picker.Please,tell me how to change color of title, the color of items and remove these lines
I have my custompicker and I could change colors of buttons CANCEL,OK
I tried to remove lines
https://forums.xamarin.com/discussion/78693/how-can-i-remove-the-picker-borders-in-forms-for-android
but it does not work
How to change color of SELECT A CAR and AUDI I do not know
You could implement it by using Custom Renderer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using App12.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Android.Graphics.Color;
using Orientation = Android.Widget.Orientation;
[assembly: ExportRenderer(typeof(Picker), typeof(MyPickerRenderer))]
namespace App12.Droid
{
public class MyPickerRenderer:PickerRenderer
{
IElementController ElementController => Element;
public MyPickerRenderer(Context context) : base(context)
{
}
private AlertDialog _dialog;
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
Control.Click += Control_Click;
Control.SetHintTextColor(Android.Graphics.Color.Red);
Control.SetSingleLine(true);
Control.SetTypeface(null, TypefaceStyle.Bold);
Control.Gravity = GravityFlags.Center;
var gd = new GradientDrawable();
gd.SetStroke(0, Android.Graphics.Color.Transparent);
Control.SetBackground(gd);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Control.Click -= Control_Click;
//var picker = (Picker)Element;
//picker.PropertyChanged -= Control_Click;
}
base.Dispose(disposing);
}
private void Control_Click(object sender, EventArgs e)
{
Picker model = Element;
picker.SelectionDividerHeight = 0;
var picker = new TextColorNumberPicker(Context);
if (model.Items != null && model.Items.Any())
{
// set style here
picker.MaxValue = model.Items.Count - 1;
picker.MinValue = 0;
picker.SetDisplayedValues(model.Items.ToArray());
picker.WrapSelectorWheel = false;
picker.Value = model.SelectedIndex;
}
var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
layout.AddView(picker);
var titleView = new TextView(Context);
titleView.Text = "Select a car";
titleView.TextSize = 20;
titleView.SetTextColor(Color.Red);
titleView.SetBackgroundColor(Color.White);
ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, true);
var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetCustomTitle(titleView);
builder.SetNegativeButton("Cancel ", (s, a) =>
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, 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("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.IsFocusedProperty, 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.IsFocusedProperty, false);
};
_dialog.Show();
Android.Widget.Button btnOk = _dialog.GetButton((int)Android.Content.DialogButtonType.Positive);
btnOk.SetTextColor(Android.Graphics.Color.Blue);
Android.Widget.Button btnCancel = _dialog.GetButton((int)Android.Content.DialogButtonType.Positive);
btnCancel.SetTextColor(Android.Graphics.Color.Gray);
}
}
public class TextColorNumberPicker : NumberPicker
{
public TextColorNumberPicker(Context context) : base(context)
{
}
public override void AddView(Android.Views.View child, int index, ViewGroup.LayoutParams #params)
{
base.AddView(child, index, #params);
UpdateView(child);
}
public void UpdateView(Android.Views.View view)
{
if (view is EditText)
{
((EditText)view).SetTextColor(Color.Red); // set item text color
}
}
}
}
Note : Make sure the Target Framework of the project is the latest stable version (Android Q) .
Override Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer instead of Xamarin.Forms.Platform.Android.PickerRenderer
public class CustomPickerRenderer
: Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
{
...
}
Reference: https://www.damirscorner.com/blog/posts/20201204-CustomPickerRendererOnAndroid.html
Related
In xamarin.forms the timepicker defaults to a clock view. I would like to use the spinner version since this fits better for the end user.
I tried this in my .xaml file
<?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"
xmlns:system="clr-namespace:System;assembly=netstandard"
mc:Ignorable="d"
x:Class="namespace.Pages.HoursWorkedPage">
<ContentPage.Content>
<StackLayout>
<DatePicker
MinimumDate="{Binding Source=(system:DateTime.Now())}"
DateSelected="DatePick er_DateSelected"/>
<TimePicker
Format="T"
android:timePickerMode="spinner"/>
Time="{Binding Source=(system:DateTime.Now.TimeOfDay())}"
PropertyChanging="OnTimeChanged"
SpinnerFormatString="t"
</StackLayout>
</ContentPage.Content>
</ContentPage>
But it give me a the error that android is not part of contentpage.
I have been looking all over the internet but I can't seem to get it fixed.
Do you want to achieve the result like following gif?
If so, you should create a custom renderer for your timePicker.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using App3.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(MyTimePicker))]
namespace App3.Droid
{
public class MyTimePicker : TimePickerRenderer
{
public MyTimePicker(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
TimePickerDialogIntervals timePickerDlg = new TimePickerDialogIntervals(this.Context, new EventHandler<TimePickerDialogIntervals.TimeSetEventArgs>(UpdateDuration),
Element.Time.Hours, Element.Time.Minutes, true);
var control = new EditText(this.Context);
control.Focusable = false;
control.FocusableInTouchMode = false;
control.Clickable = false;
control.Click += (sender, ea) => timePickerDlg.Show();
control.Text = Element.Time.Hours.ToString("00") + ":" + Element.Time.Minutes.ToString("00");
SetNativeControl(control);
}
void UpdateDuration(object sender, Android.App.TimePickerDialog.TimeSetEventArgs e)
{
Element.Time = new TimeSpan(e.HourOfDay, e.Minute, 0);
Control.Text = Element.Time.Hours.ToString("00") + ":" + Element.Time.Minutes.ToString("00");
}
}
public class TimePickerDialogIntervals : TimePickerDialog
{
public const int TimePickerInterval = 15;
private bool _ignoreEvent = false;
public TimePickerDialogIntervals(Context context, EventHandler<TimePickerDialog.TimeSetEventArgs> callBack, int hourOfDay, int minute, bool is24HourView)
: base(context, TimePickerDialog.ThemeHoloLight, (sender, e) =>
{
callBack(sender, new TimePickerDialog.TimeSetEventArgs(e.HourOfDay, e.Minute * 5));
}, hourOfDay, minute / TimePickerInterval, is24HourView)
{
}
protected TimePickerDialogIntervals(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void SetView(Android.Views.View view)
{
SetupMinutePicker(view);
base.SetView(view);
}
void SetupMinutePicker(Android.Views.View view)
{
var numberPicker = FindMinuteNumberPicker(view as ViewGroup);
if (numberPicker != null)
{
numberPicker.MinValue = 0;
numberPicker.MaxValue = 11;
numberPicker.SetDisplayedValues(new String[] { "00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55" });
}
}
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
GetButton((int)DialogButtonType.Negative).Visibility = Android.Views.ViewStates.Gone;
this.SetCanceledOnTouchOutside(false);
}
private NumberPicker FindMinuteNumberPicker(ViewGroup viewGroup)
{
for (var i = 0; i < viewGroup.ChildCount; i++)
{
var child = viewGroup.GetChildAt(i);
var numberPicker = child as NumberPicker;
if (numberPicker != null)
{
if (numberPicker.MaxValue == 59)
{
return numberPicker;
}
}
var childViewGroup = child as ViewGroup;
if (childViewGroup != null)
{
var childResult = FindMinuteNumberPicker(childViewGroup);
if (childResult != null)
return childResult;
}
}
return null;
}
}
}
I am using CustomMapRenderer.cs and ExtendedMap.cs to draw polylines on the map with the tap (touch event).
ExtendedMap.cs is in the MapTap (Portable) project while the CustomMapRenderer.cs is in MapTap.Android project in the Visual Studio 2015 solution.
CustomMapRenderer.cs
using System.Collections.Generic;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using MapTap;
using MapTap.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using System;
[assembly: ExportRenderer(typeof(ExtendedMap), typeof(CustomMapRenderer))]
[assembly: Dependency(typeof(CustomMapRenderer))]
namespace MapTap.Droid
{
public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback,ClearPolyline
{
GoogleMap map;
List<LatLng> polygontest = new List<LatLng>();
public CustomMapRenderer()
{
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
if (map != null)
map.MapClick -= googleMap_MapClick;
base.OnElementChanged(e);
if (Control != null)
((MapView)Control).GetMapAsync(this);
}
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
if (map != null)
map.MapClick += googleMap_MapClick; ;
}
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
polygontest.Add(new LatLng(e.Point.Latitude, e.Point.Longitude));
((ExtendedMap)Element).OnTap(new Position(e.Point.Latitude, e.Point.Longitude));
if (polygontest.Count >1 )
{
AddPolygons();
}
}
public void Clearline()
{
map.Clear();
}
void AddPolygons()
{
var polygonOptions = new PolylineOptions();
polygonOptions.InvokeColor(0x66FF0000);
foreach (var position in polygontest)
{
polygonOptions.Add(new LatLng(position.Latitude, position.Longitude));
}
map.AddPolyline(polygonOptions);
polygontest.RemoveAt(0);
}
}
}
ExtendedMap.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Xamarin.Forms;
namespace MapTap
{
public class ExtendedMap : Map
{
public event EventHandler<TapEventArgs> Tap;
public ExtendedMap()
{
}
public ExtendedMap(MapSpan region) : base(region)
{
}
public void OnTap(Position coordinate)
{
OnTap(new TapEventArgs { Position = coordinate });
var lat = coordinate.Latitude;
var lng = coordinate.Longitude;
putpinonclick(lat,lng);
}
public void putpinonclick(double lat, double lng)
{
var pin = new Pin
{
Type = PinType.SavedPin,
Position = new Position(lat, lng),
Label = "Xamarin San Francisco Office",
Address = "394 Pacific Ave, San Francisco CA"
};
this.Pins.Add(pin);
}
protected virtual void OnTap(TapEventArgs e)
{
var handler = Tap;
if (handler != null) handler(this, e);
}
}
public class TapEventArgs : EventArgs
{
public Position Position { get; set; }
}
}
I want to clear polylines on button click (Clear Button) from the MainPage.xaml.
Following is a screenshot of the running application:
Screenshot
I am calling a function of CustomMapRendrer.cs from MainPage.Xaml.cs using
var test = DependencyService.Get<ClearPolyline>();
test.Clearline();
ClearPolyLine is an interface and Clearline in the function of interface which is implemented in CustomMapRender
The problem is that when I call the above line of code, the variable test itself is not null, but all of its member variables (implemented in CustomMapRenderer) are null. test is of type ClearPolyline.
How to resolve this issue?
PolyLine addedLine = map.AddPolyline(polygonOptions);
This should return the added PolyLine so store this Ployline(s) in a property or collection.
On button click or command disturb RemovePolyline property (Custom bindable property) of the ExtendedMap and listen to the property changes in the extended renderer and based on the value call addedLine.remove(); or loop in the collection of polylines and remove it.
Entry.unfocus/Entry.completed hides keyboard, how to cancel it?
I have a page with some entries and when I press keyboard enter key, I want the keyboard not hides. How to do that with PCL project (Android e iOS)?
Just to point out another solution for Android. In case you want to keep always visible the keyboard for a specific Editor Renderer, you need to override the following methods in the MainActivity class:
private bool _lieAboutCurrentFocus;
public override bool DispatchTouchEvent(MotionEvent ev)
{
var focused = CurrentFocus;
bool customEntryRendererFocused = focused != null && focused.Parent is YourCustomEditorRenderer;
_lieAboutCurrentFocus = customEntryRendererFocused;
var result = base.DispatchTouchEvent(ev);
_lieAboutCurrentFocus = false;
return result;
}
public override Android.Views.View CurrentFocus
{
get
{
if (_lieAboutCurrentFocus)
{
return null;
}
return base.CurrentFocus;
}
}
You can find a more detail explanation here
Hope this helps.
Regards
If you want to do that from the PCL there's a nice and easy way to navigate through your entries and keep them focused one after the other (If this is what you're looking for, and not just keep keyboard open)
Let's say you have around 5 entries in your page, and you want to cycle through them when user presses the done or enter key.
CurrentPage.FindByName<Entry>("FirstEntry").Completed += (o, args) =>
{
CurrentPage.FindByName<Entry>("SecondEntry").Focus();
};
CurrentPage.FindByName<Entry>("SecondEntry").Completed += (o, args) =>
{
CurrentPage.FindByName<Entry>("ThirdEntry").Focus();
};
CurrentPage.FindByName<Entry>("ThirdEntry").Completed += (o, args) =>
{
CurrentPage.FindByName<Entry>("ForthEntry").Focus();
};
CurrentPage.FindByName<Entry>("ForthEntry").Completed += (o, args) =>
{
CurrentPage.FindByName<Entry>("FifthEntry").Focus();
};
CurrentPage.FindByName<Entry>("FifthEntry").Completed += (o, args) =>
{
//Keep going or execute your command, you got the drill..
};
You can add this to your ViewIsAppearing or Init method.
Recently i did something similar. I want to keep keyboard always open in a page and not to hide when a button clicked. To accomplish this, i followed different ways both on iOS and Android.
iOS
In iOS, i created a custom editor renderer
public class CustomEditorRenderer : EditorRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
var element = this.Element as CustomEditor;
Control.InputAccessoryView = null;
Control.ShouldEndEditing += DisableHidingKeyboard;
MessagingCenter.Subscribe<ReportEventDetailPage>(this, "FocusKeyboardStatus", (sender) =>
{
if (Control != null)
{
Control.ShouldEndEditing += EnableHidingKeyboard;
}
MessagingCenter.Unsubscribe<ReportEventDetailPage>(this, "FocusKeyboardStatus");
});
}
private bool DisableHidingKeyboard(UITextView textView)
{
return false;
}
private bool EnableHidingKeyboard(UITextView textView)
{
return true;
}
}
In this piece of code:
Control.ShouldEndEditing += DisableHidingKeyboard; makes keyboard always opened after focusing custom editor. However, the keyboard does not hide when changing current page to another page. To solve this problem i used MessagingCenter and when dissapering of the current page i send a message to hide keyboard.
Android
For Android, i created a keyboard helper interface and implemented it.
Here is my interface:
public interface IKeyboardHelper
{
void ShowKeyboard();
void HideKeyboard();
}
Keyboard Helper class for Android:
public class KeyboardHelper : IKeyboardHelper
{
public void ShowKeyboard()
{
var context = Forms.Context;
var inputMethodManager = context.GetSystemService(Context.InputMethodService) as InputMethodManager;
if (inputMethodManager != null && context is Activity)
{
var activity = context as Activity;
var token = activity.CurrentFocus?.WindowToken;
inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
}
}
public void HideKeyboard()
{
var context = Forms.Context;
var inputMethodManager = context.GetSystemService(Context.InputMethodService) as InputMethodManager;
if (inputMethodManager != null && context is Activity)
{
var activity = context as Activity;
var token = activity.CurrentFocus?.WindowToken;
inputMethodManager.HideSoftInputFromWindow(token, HideSoftInputFlags.None);
activity.Window.DecorView.ClearFocus();
}
}
in Constructor of the current page:
else if (Device.OS == TargetPlatform.Android)
{
MessagingCenter.Send(this, "AndroidFocusEditor");
}
and OnAppearing method of the current page:
protected override void OnAppearing()
{
base.OnAppearing();
if (Device.OS == TargetPlatform.Android)
{
DependencyService.Get<IKeyboardHelper>().ShowKeyboard();
//EventEditor.Focus();
MessagingCenter.Subscribe<ReportEventDetailPage>(this, "AndroidFocusEditor", (sender) => {
Device.BeginInvokeOnMainThread(async () => {
await Task.Run(() => Task.Delay(1));
EventEditor.Focus();
MessagingCenter.Unsubscribe<ReportEventDetailPage>(this, "AndroidFocusEditor");
});
});
}
else if (Device.OS == TargetPlatform.iOS)
{
EventEditor.Focus();
}
}
One last thing: if user clicks another button on the page, keyboard is hiding. To prevent this i followed this link and it really helped me a lot
Keep Keyboard Open For Android
In case you have a custom Keyboard, you can implement a "show" and a "hide" method on android renderer.
Then on your page, show keyboard on your custom control without hiding it. You can hide it when changing page, by overriding OnBackButtonPressed.
In OnBackButtonPressed, send a message using MessagingCenter. Then subscribe to it on your custom control constructor.
Declare an EventHandler that you invoke in the callback method.
Subscribe to this event on your android custom entry renderer and hide the keyboard there.
I had a similar problem and handled it like below:
using System.Runtime.CompilerServices;
using Xamarin.Forms;
public class CustomEntry: Entry
{
public static readonly BindableProperty KeyboardAliveProperty =
BindableProperty.Create(nameof(KeyboardAliveType), typeof(KeyboardAliveType),
typeof(CustomEntry), KeyboardAliveType.Default);
public KeyboardAliveType KeyboardAliveType
{
get { return (KeyboardAliveType)GetValue(KeyboardAliveProperty); }
set { SetValue( KeyboardAliveProperty, value);}
}
}
public enum KeyboardAliveType
{
Default =0,
OnCompleted = 1,
OnButtonClicked = 2,
OnCompletedAndButtonClicked = 3
}
Renderer for Android:
using System;
using Android.Content;
using Android.OS;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Entry = Xamarin.Forms.Entry;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
/// <summary>
/// Allow and support changes to Border styling and Keyboard with Custom Entry.
/// </summary>
public class CustomEntryRenderer: EntryRenderer, TextView.IOnEditorActionListener
{
private ImeAction _currentInputImeFlag;
public CustomEntryRenderer(Context context) : base(context)
{
//do nothiing
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement!=null)
{
}
}
bool TextView.IOnEditorActionListener.OnEditorAction(TextView v, ImeAction actionId, KeyEvent e)
{
// Fire Completed and dismiss keyboard for hardware / physical keyboards
if (actionId == ImeAction.Done || actionId == _currentInputImeFlag ||
(actionId == ImeAction.ImeNull && e.KeyCode == Keycode.Enter && e.Action == KeyEventActions.Up))
{
global::Android.Views.View nextFocus = null;
if (_currentInputImeFlag == ImeAction.Next)
{
nextFocus = FocusSearch(v, FocusSearchDirection.Forward);
}
if (nextFocus != null)
{
nextFocus.RequestFocus();
if (!nextFocus.OnCheckIsTextEditor())
{
if (Element is CustomEntry cE)
{
if (cE.KeyboardAliveType != KeyboardAliveType.OnCompleted &&
cE.KeyboardAliveType != KeyboardAliveType.OnCompletedAndButtonClicked)
{
v.HideKeyboard();
}
}
}
}
else
{
EditText.ClearFocus();
if (Element is CustomEntry cE)
{
if (cE.KeyboardAliveType != KeyboardAliveType.OnCompleted &&
cE.KeyboardAliveType != KeyboardAliveType.OnCompletedAndButtonClicked)
{
v.HideKeyboard();
}
}
}
((IEntryController)Element).SendCompleted();
}
return true;
}
}
internal static class CustomEntryRendererExtensions
{
internal static void HideKeyboard(this Android.Views.View inputView, bool overrideValidation = false)
{
if (inputView == null)
throw new ArgumentNullException(nameof(inputView) + " must be set before the keyboard can be hidden.");
using (var inputMethodManager = (InputMethodManager)inputView.Context?.GetSystemService(Context.InputMethodService))
{
if (!overrideValidation && !(inputView is EditText || inputView is TextView || inputView is SearchView))
throw new ArgumentException("inputView should be of type EditText, SearchView, or TextView");
IBinder windowToken = inputView.WindowToken;
if (windowToken != null && inputMethodManager != null)
inputMethodManager.HideSoftInputFromWindow(windowToken, HideSoftInputFlags.None);
}
}
}
In MainActivity.cs
private bool _lieAboutCurrentFocus;
public override bool DispatchTouchEvent(MotionEvent ev)
{
var focused = CurrentFocus;
if (focused?.Parent is CustomEntryRenderer cer)
{
if (cer.Element is CustomEntry cEntry)
{
if (cEntry.KeyboardAliveType == KeyboardAliveType.OnButtonClicked ||
cEntry.KeyboardAliveType == KeyboardAliveType.OnCompletedAndButtonClicked)
{
_lieAboutCurrentFocus = true;
}
}
}
var result = base.DispatchTouchEvent(ev);
_lieAboutCurrentFocus = false;
return result;
}
public override Android.Views.View CurrentFocus
{
get
{
if (_lieAboutCurrentFocus)
{
return null;
}
return base.CurrentFocus;
}
}
Renderer for UWP:
using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.System;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
public class CustomEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// Remove the EventHandler set for KeyUp, and add my custom EventHandler.
// Had to do it this way (using WindowsRuntimeMarshal) because the Delegate that
// I want to remove from the KeyUp event is marked private in a different assembly, so no way to access it directly.
// This way I can customize how the keyboard behaves when the Enter key is pressed.
/*Done the best I can for UWP.*/
var keyUpRuntimeEvent = this.Control.GetType().GetRuntimeEvent("KeyUp");
Action<EventRegistrationToken> removeEventHandlerAction =
(Action<EventRegistrationToken>)Delegate.CreateDelegate(typeof(Action<EventRegistrationToken>),
this.Control,
keyUpRuntimeEvent.RemoveMethod);
WindowsRuntimeMarshal.RemoveAllEventHandlers(removeEventHandlerAction);
this.Control.KeyUp += TextBoxOnKeyUp;
this.Control.PreventKeyboardDisplayOnProgrammaticFocus = false;
// Just to make sure that keyboard is up when the Entry is focused.
Control.GotFocus += (sender, args) =>
{
AttemptToForceKeyboardToShow(Control);
};
Control.TextChanged += (sender, args) =>
{
if (Control.FocusState != FocusState.Unfocused)
{
AttemptToForceKeyboardToShow(Control);
}
};
}
}
protected override void Dispose(bool disposing)
{
if (disposing && Control != null)
{
Control.KeyUp -= TextBoxOnKeyUp;
}
base.Dispose(disposing);
}
private void TextBoxOnKeyUp(object sender, KeyRoutedEventArgs args)
{
if (args?.Key != VirtualKey.Enter)
{
return;
}
if (Element.ReturnType == ReturnType.Next)
{
FocusManager.TryMoveFocus(FocusNavigationDirection.Next);
}
else
{
/*Done the best I can for UWP.*/
if (Element is CustomEntry cE)
{
if (cE.KeyboardAliveType != KeyboardAliveType.OnCompleted &&
cE.KeyboardAliveType != KeyboardAliveType.OnCompletedAndButtonClicked)
{
//Hide the soft keyboard; this matches the behavior of Forms on Android/iOS
Windows.UI.ViewManagement.InputPane.GetForCurrentView().TryHide();
}
}
}
((IEntryController)Element).SendCompleted();
}
private void AttemptToForceKeyboardToShow(FormsTextBox control)
{
try
{
var inputPane = InputPane.GetForUIContext(control.UIContext);
var keyboardShowSuccess = inputPane?.TryShow();
if (keyboardShowSuccess == null || !keyboardShowSuccess.Value)
{
Console.WriteLine("Attempt to force Keyboard to show failed on Windows.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
See here.
I added a property to my webpart main.cs
public override ToolPart[] GetToolParts()
{
ToolPart[] toolparts = new ToolPart[4];
WebPartToolPart wptp = new WebPartToolPart();
CustomPropertyToolPart custom = new CustomPropertyToolPart();
CalendarToolPart datumswahl = new CalendarToolPart("Coutdown Datum Wahl");
toolparts[0] = datumswahl;
toolparts[1] = custom;
toolparts[2] = wptp;
return toolparts;
}
I then built this class toolpartClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace Custom_Toolpart.toolparttest
{
class CalendarToolPart : ToolPart
{
public Calendar datumWahl = null;
private void CalendarToolPart_Init(object sender, EventArgs e)
{
datumWahl = new Calendar();
datumWahl.ID = "datumWahl";
SyncChanges();
}
public CalendarToolPart(string strTitle)
{
this.Title = strTitle;
this.Init += new EventHandler(CalendarToolPart_Init);
}
public override void ApplyChanges()
{
//base.ApplyChanges();
EnsureChildControls();
}
public override void SyncChanges()
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Controls.Add(datumWahl);
this.ChildControlsCreated = true; //?
}
}
My problem is, that I can't use/call the calendar out of the toolpartClass.cs
What I want to do is, that the selected date is given to the "toolpartUserControl.ascx.cs" (the code behind) where I want to use the date and display a result in the toolpart.ascx
It is no problem to use the "normal" added webpart properties in the toolpartUserControl.ascx.cs, like here
namespace Custom_Toolpart.toolparttest
{
public partial class toolparttestUserControl : UserControl
{
public toolparttest WebPart { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
DateTime datumAuswahl1 = DateTime.Parse(Calendar1.SelectedDate.ToString("MM") + "/" + Calendar1.SelectedDate.ToString("dd") + "/" + Calendar1.SelectedDate.ToString("yyyy"));
DateTime datumJetzt = DateTime.Now;
TimeSpan mySpan = new TimeSpan(-24, 0, 0);
datumJetzt = datumJetzt.Add(mySpan);
TimeSpan laufzeit = datumAuswahl1 - datumJetzt;
string ausgabeLaufzeit = string.Format("{0}", laufzeit.Days);
int i = Convert.ToInt32(ausgabeLaufzeit);
if (i >= 2)
{
lbl_6.Text = "Tage";
}
if (i == 1)
{
lbl_6.Text = "Tag";
}
if (i == 0)
{
lbl_6.Text = "Tage";
lbl_hide.Visible = true;
lbl_1.Visible = false;
lbl_2.Visible = false;
lbl_3.Visible = false;
lbl_6.Visible = false;
}
lbl_2.Text = ausgabeLaufzeit;
if (this.WebPart != null && this.WebPart.CountDown_Text != null)
{
lbl_1.Text = this.WebPart.CountDown_Text.ToString();
}
if (this.WebPart != null && this.WebPart.Event_Text != null)
{
lbl_3.Text = this.WebPart.Event_Text.ToString();
}
if (this.WebPart != null && this.WebPart.Header_Text != null)
{
lbl_4.Text = this.WebPart.Header_Text.ToString();
}
if (this.WebPart != null && this.WebPart.Main_Text != null)
{
lbl_5.Text = this.WebPart.Main_Text.ToString();
}
if (this.WebPart != null && this.WebPart.Link_Edit != null)
{
hyplnk_1.NavigateUrl = this.WebPart.Link_Edit.ToString();
}
if (this.WebPart != null && this.WebPart.Ablauf_Text != null)
{
lbl_hide.Text = this.WebPart.Ablauf_Text.ToString();
}
}
}
}
How can I send the selected date to the toolpartUserControl.ascx.cs class?
Hi
There is a behavior in following code
I want to use this behavior in my WPF application
But i cant attached this behavior to my project
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.ComponentModel;
namespace Brainsiders.MouseOver3D
{
[Description("MouseOver3D - A behavior that applies the MouseOver Design Interaction Pattern to a 3D environment.")]
public class MouseOver3D : TargetedTriggerAction<FrameworkElement>
{
private TimeSpan hoverUp_duration = TimeSpan.FromSeconds(0.5);
[Category("Mouse Over 3D - Going Up")]
public TimeSpan HoverUp_duration
{
get { return hoverUp_duration; }
set { hoverUp_duration = value; }
}
private TimeSpan hoverDown_Duration = TimeSpan.FromSeconds(0.9);
[Category("Mouse Over 3D - Going Down")]
public TimeSpan HoverDown_Duration
{
get { return hoverDown_Duration; }
set { hoverDown_Duration = value; }
}
[Category("Mouse Over 3D - Going Up")]
public IEasingFunction HoverUp_Easing { get; set; }
[Category("Mouse Over 3D - Going Down")]
public IEasingFunction HoverDown_Easing { get; set; }
private double hoverOffset = 30;
[Category("Mouse Over 3D - General")]
public double HoverOffset
{
get { return hoverOffset; }
set { hoverOffset = value; }
}
private FrameworkElement feAssociatedObject;
private FrameworkElement feSourceObject;
private FrameworkElement feTargetObject;
private PlaneProjection ProjectionTargetObject;
private Storyboard SB_HoverZ;
protected override void Invoke(object parameter)
{
FrameworkElement myElement = this.AssociatedObject as FrameworkElement;
}
protected override void OnAttached()
{
base.OnAttached();
feAssociatedObject = (FrameworkElement)this.AssociatedObject;
feSourceObject = (FrameworkElement)this.AssociatedObject;
feSourceObject.Loaded += new RoutedEventHandler(feSourceObject_Loaded);
}
void feSourceObject_Loaded(object sender, RoutedEventArgs e)
{
feSourceObject.Loaded -= new RoutedEventHandler(feSourceObject_Loaded);
ProjectionTargetObject = new PlaneProjection();
feTargetObject = (FrameworkElement)this.TargetObject;
if (feTargetObject == null) feTargetObject = feAssociatedObject;
if (feTargetObject.Projection == null)
{
feTargetObject.RenderTransformOrigin = new Point(0.5, 0.5);
PlaneProjection pj = new PlaneProjection();
feTargetObject.Projection = pj;
}
feSourceObject.MouseEnter += new MouseEventHandler(feSourceObject_MouseEnter);
feSourceObject.MouseLeave += new MouseEventHandler(feSourceObject_MouseLeave);
}
protected override void OnDetaching()
{
base.OnDetaching();
}
void feSourceObject_MouseLeave(object sender, MouseEventArgs e)
{
DeactivateAnimation();
}
void feSourceObject_MouseEnter(object sender, MouseEventArgs e)
{
ActivateAnimation();
}
bool bAnimationActivated = false;
private void ActivateAnimation()
{
if (bAnimationActivated == false)
{
AnimateHoverZ(HoverOffset, true);
bAnimationActivated = true;
}
}
private void DeactivateAnimation()
{
if (bAnimationActivated == true)
{
AnimateHoverZ(0, false);
bAnimationActivated = false;
}
}
private void AnimateHoverZ( Double Z, bool HoverUp)
{
if (HoverUp == true)
playAnimation(feTargetObject, "(UIElement.Projection).(PlaneProjection.LocalOffsetZ)", HoverUp_duration, Z, SB_HoverZ, HoverUp_Easing);
else
playAnimation(feTargetObject, "(UIElement.Projection).(PlaneProjection.LocalOffsetZ)", HoverDown_Duration, Z, SB_HoverZ, HoverDown_Easing);
}
public static void playAnimation(FrameworkElement element, string property, TimeSpan time, double value, Storyboard sb, IEasingFunction EasingFunction)
{
sb = new Storyboard();
sb.Children.Clear();
DoubleAnimation animation = new DoubleAnimation();
animation.Duration = time;
animation.To = value;
animation.EasingFunction = EasingFunction;
Storyboard.SetTargetProperty(animation, new PropertyPath(property));
Storyboard.SetTarget(animation, element);
sb.Children.Add(animation);
sb.Begin();
}
}
}
You need to add the necessary references (System.Windows.Interactivity)
to your project, for that you need to have some version of the Blend SDK installed.
Then to use this in XAML you need to define namespaces for both interactivity and this behavior:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:bs="clr-namespace:Brainsiders.MouseOver3D"
Then you should be able to attach it like this:
<Button>
<i:Interaction.Behaviors>
<bs:MouseOver3D />
</i:Interaction.Behaviors>
</Button>