首先,我想在X.F中使用名为JVFloatLabeledEntry的自定义UITextField。以下是对此自定义UITextField https://github.com/gshackles/JVFloatSharp
的引用所以这是我的步骤:
XF方面: 1. JVFloatLabeledEntry.cs
public class JVFloatLabeledEntry : Entry
{
public Color FloatingLabelColor { get; private set;}
public Color FloatingLabelActiveColor { get; private set;}
public JVFloatLabeledEntry () : base()
{
WidthRequest = 300;
HeightRequest = 44;
FloatingLabelColor = Color.Gray;
FloatingLabelActiveColor = Color.Black;
}
}
iOS方面: 2. JVFloatLabeledTextField.cs这是我想要使用的自定义UITextField。你可以在github https://github.com/gshackles/JVFloatSharp找到这个文件 3. JVFloatLabeledEntryRenderer.cs这是我的CustomRenderer,它创建一个全新的JVFloatLabeledTextField并将其设置为NativeControl
[assembly: ExportRenderer (typeof (JVFloatLabeledEntry), typeof (JVFloatLabeledEntryRenderer))]
namespace DutyFreeCollection.iOS
{
public class JVFloatLabeledEntryRenderer : ViewRenderer<JVFloatLabeledEntry, JVFloatLabeledTextField>
{
public JVFloatLabeledEntryRenderer () {}
protected override void OnElementChanged (ElementChangedEventArgs<JVFloatLabeledEntry> e)
{
base.OnElementChanged (e);
var jfflEntry = e.NewElement;
if (jfflEntry != null) {
const float JVFieldHMargin = 10.0f;
const float JVFieldFontSize = 16.0f;
const float JVFieldFloatingLabelFontSize = 11.0f;
// Now whenever I use JVFloatLabeledEntry on XF side, this newView is instead used
var newView = new JVFloatLabeledTextField (
new RectangleF(JVFieldHMargin, 0, (float)jfflEntry.WidthRequest, (float)jfflEntry.HeightRequest))
{
Text = jfflEntry.Text,
Placeholder = jfflEntry.Placeholder,
Font = UIFont.SystemFontOfSize (JVFieldFontSize),
ClearButtonMode = UITextFieldViewMode.WhileEditing,
FloatingLabelFont = UIFont.BoldSystemFontOfSize (JVFieldFloatingLabelFontSize),
FloatingLabelTextColor = jfflEntry.FloatingLabelColor.ToUIColor(),
FloatingLabelActiveTextColor = jfflEntry.FloatingLabelActiveColor.ToUIColor(),
BorderStyle = UITextBorderStyle.RoundedRect
};
SetNativeControl (newView);
}
}
}
}
我的问题是在将新的JVFloatLabeledTextField设置为本机控件之后,所有成员(如事件TextChanged)和XF端的Entry的TextProperty之类的属性都消失了。即。
JVFloatLabeledEntry floatLabeledEntry = new JVFloatLabeledEntry();
floatLabeledEntry.TextChanged += (object sender, TextChangedEventArgs e) => {
// Never comes here, event TextChanged of JVFloatLabeledEntry is gone, but why? Since JVFloatLabeledEntry derived from Entry, why is the event TextChanged gone?
};
此自定义条目的所有其他成员也会发生同样的事情,例如
floatLabeledEntry.SetBinding(JVFloatLabeledEntry.TextProperty, "ANY_BINDING_FIELD"); // The two-way binding is gone as well.
我真的到了瓶颈,有人可以告诉我如何保留JVFloatLabeledEntry(CustomEntry)的基类Entry属性绑定和EventHandlers。非常感谢你。
答案 0 :(得分:1)
如果我正确理解了这个问题,那么问题在于你初始化iOS本机控件的方式 - 没有你在本机上听的事件(包括缺少绑定),你正在初始化本能控制以一种发射后的方式。
您需要添加代码才能将本机事件转换为表单事件。我对您正在使用的自定义控件不够熟悉,但在启动控件后,在渲染器中,您需要挂钩其事件,这就是:
newView.TextChangedEvent+=(s,e) => jfflEntry.OnTextChanged(jffl, new TextChangedEventArgs(e.NewText);
上面的代码已经完成,但它应该让你知道该怎么做,如果不是 - 只要问一下“不清楚”
答案 1 :(得分:0)
这是我的解决方案:
[assembly: ExportRenderer (typeof (JVFloatLabeledEntry), typeof (JVFloatLabeledEntryRenderer))]
namespace DutyFreeCollection.iOS
{
public class JVFloatLabeledEntryRenderer : ViewRenderer<JVFloatLabeledEntry, JVFloatLabeledTextField>
{
private UIColor defaultTextColor;
public JVFloatLabeledEntryRenderer () {}
protected override void OnElementChanged (ElementChangedEventArgs<JVFloatLabeledEntry> e)
{
base.OnElementChanged (e);
var jfflEntry = e.NewElement;
if (jfflEntry != null) {
const float JVFieldHMargin = 10.0f;
const float JVFieldFontSize = 16.0f;
const float JVFieldFloatingLabelFontSize = 11.0f;
var newView = new JVFloatLabeledTextField (
new RectangleF(JVFieldHMargin, 0, (float)jfflEntry.WidthRequest, (float)jfflEntry.HeightRequest))
{
Text = jfflEntry.Text,
Placeholder = jfflEntry.Placeholder,
Font = UIFont.SystemFontOfSize (JVFieldFontSize),
ClearButtonMode = UITextFieldViewMode.WhileEditing,
FloatingLabelFont = UIFont.BoldSystemFontOfSize (JVFieldFloatingLabelFontSize),
FloatingLabelTextColor = jfflEntry.FloatingLabelColor.ToUIColor(),
FloatingLabelActiveTextColor = jfflEntry.FloatingLabelActiveColor.ToUIColor(),
BorderStyle = UITextBorderStyle.RoundedRect
};
SetNativeControl (newView);
this.UpdatePlaceholder ();
this.UpdatePassword ();
this.UpdateText ();
this.UpdateColor ();
this.UpdateKeyboard ();
newView.EditingChanged += delegate (object sender, EventArgs a) {
jfflEntry.Text = newView.Text;
};
newView.ShouldReturn = new UITextFieldCondition (this.OnShouldReturn);
// newView.EditingDidBegin += delegate (object sender, EventArgs args) {
// jfflEntry.IsFocused = true;
// };
// newView.EditingDidEnd += delegate (object sender, EventArgs args) {
// jfflEntry.IsFocused = false;
// };
this.defaultTextColor = newView.TextColor;
MessagingCenter.Subscribe<IVisualElementRenderer> (this, "Xamarin.ResignFirstResponder", delegate (IVisualElementRenderer sender) {
if (newView.IsFirstResponder) {
newView.ResignFirstResponder ();
}
}, null);
}
}
protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
{
Entry arg_06_0 = base.Element;
if (e.PropertyName == Entry.PlaceholderProperty.PropertyName) {
this.UpdatePlaceholder ();
}
else {
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName) {
this.UpdatePassword ();
}
else {
if (e.PropertyName == Entry.TextProperty.PropertyName) {
this.UpdateText ();
}
else {
if (e.PropertyName == Entry.TextColorProperty.PropertyName) {
this.UpdateColor ();
}
else {
if (e.PropertyName == Xamarin.Forms.InputView.KeyboardProperty.PropertyName) {
this.UpdateKeyboard ();
}
}
}
}
}
base.OnElementPropertyChanged (sender, e);
}
private bool OnShouldReturn (UITextField view)
{
base.Control.ResignFirstResponder ();
// base.Element.SendCompleted ();
return true;
}
private void UpdateColor ()
{
if (base.Element.TextColor == Color.Default) {
base.Control.TextColor = this.defaultTextColor;
return;
}
base.Control.TextColor = base.Element.TextColor.ToUIColor ();
}
private void UpdateKeyboard ()
{
base.Control.ApplyKeyboard (base.Element.Keyboard);
}
private void UpdatePassword ()
{
if (base.Element.IsPassword && base.Control.IsFirstResponder) {
base.Control.Enabled = false;
base.Control.SecureTextEntry = true;
base.Control.Enabled = base.Element.IsEnabled;
base.Control.BecomeFirstResponder ();
return;
}
base.Control.SecureTextEntry = base.Element.IsPassword;
}
private void UpdatePlaceholder ()
{
base.Control.Placeholder = base.Element.Placeholder;
}
private void UpdateText ()
{
if (base.Control.Text != base.Element.Text) {
base.Control.Text = base.Element.Text;
}
}
}
}
但是我无法设置jfflEntry.IsFocused,因为IsFocused是VisualElement中的内部属性,任何人都知道如何访问或设置Entry的IsFocused属性? 对于base.Element.SendCompleted();
也是如此