728x90

Editer 컨트롤에는 불행하게요 PlaceHolder 관련 속성이 없습니다.

(PlaceHolderColor 는 최근에 추가된 속성입니다.)

이를 만드는 방법입니다.

먼저 기본은 지난 글을 기본으로 해서 진행합니다.

 

.Net Statndrd 프로젝트에 CustomEditor 를 추가합니다.

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace Test.Controls
{
    public class CustomEditor : Editor
    {
        public static BindableProperty PlaceholderProperty
         = BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(CustomEditor));

        public static BindableProperty PlaceholderColorProperty
           = BindableProperty.Create(nameof(PlaceholderColor), typeof(Color), typeof(CustomEditor), Color.Gray);

        public static BindableProperty IsExpandableProperty
        = BindableProperty.Create(nameof(IsExpandable), typeof(bool), typeof(CustomEditor), false);

        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }

        public Color PlaceholderColor
        {
            get { return (Color)GetValue(PlaceholderColorProperty); }
            set { SetValue(PlaceholderColorProperty, value); }
        }

        public bool IsExpandable
        {
            get { return (bool)GetValue(IsExpandableProperty); }
            set { SetValue(IsExpandableProperty, value); }
        }

        public CustomEditor()
        {
            TextChanged += OnTextChanged;
        }

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            if (IsExpandable) InvalidateMeasure();
        }
    }
}

 

Android 프로젝트에 CustomEditorRenderer 를 추가합니다.

using Android.Content;
using Android.Graphics.Drawables;
using Test.Controls;
using Test.Droid;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))]
namespace Test.Droid
{
    public class CustomEditorRenderer : EditorRenderer
    {
        public CustomEditorRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Editor> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                // 밑줄을 보이지 않도록 하기
                GradientDrawable gd = new GradientDrawable();
                gd.SetColor(global::Android.Graphics.Color.Transparent);
                this.Control.SetBackgroundDrawable(gd);
            }

            if (e.NewElement != null)
            {
                var customControl = (CustomEditor)Element;

                if (!string.IsNullOrEmpty(customControl.Placeholder))
                {
                    Control.Hint = customControl.Placeholder;
                    Control.SetHintTextColor(customControl.PlaceholderColor.ToAndroid());
                }
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            var customControl = (CustomEditor)Element;

            if (CustomEditor.PlaceholderProperty.PropertyName == e.PropertyName)
            {
                Control.Hint = customControl.Placeholder;
            }
            else if (CustomEditor.PlaceholderColorProperty.PropertyName == e.PropertyName)
            {
                Control.SetHintTextColor(customControl.PlaceholderColor.ToAndroid());
            }
        }
    }
}

 

iOS 프로젝트에 CustomEditorRenderer 를 추가합니다.

using Foundation;
using Test.Controls;
using Test.iOS;
using System.ComponentModel;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))]
namespace Test.iOS
{
    public class CustomEditorRenderer : EditorRenderer
    {
        UILabel placeholderLabel;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Editor> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                if (placeholderLabel == null)
                {
                    CreatePlaceholder();
                }
            }

            if (e.NewElement != null)
            {
                var customControl = (CustomEditor)e.NewElement;

                if (customControl.IsExpandable)
                    Control.ScrollEnabled = false;
                else
                    Control.ScrollEnabled = true;
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            var customControl = (CustomEditor)Element;

            if (CustomEditor.IsExpandableProperty.PropertyName == e.PropertyName)
            {
                if (customControl.IsExpandable)
                    Control.ScrollEnabled = false;
                else
                    Control.ScrollEnabled = true;
            }
        }

        public void CreatePlaceholder()
        {
            var element = Element as CustomEditor;

            if (element == null) return;

            placeholderLabel = new UILabel
            {
                Text = element.Placeholder,
                TextColor = element.PlaceholderColor.ToUIColor(),
                BackgroundColor = UIColor.Clear
            };

            var edgeInsets = Control.TextContainerInset;
            var lineFragmentPadding = Control.TextContainer.LineFragmentPadding;

            Control.AddSubview(placeholderLabel);

            var vConstraints = NSLayoutConstraint.FromVisualFormat(
                "V:|-" + edgeInsets.Top + "-[PlaceholderLabel]-" + edgeInsets.Bottom + "-|", 0, new NSDictionary(),
                NSDictionary.FromObjectsAndKeys(
                    new NSObject[] { placeholderLabel }, new NSObject[] { new NSString("PlaceholderLabel") })
            );

            var hConstraints = NSLayoutConstraint.FromVisualFormat(
                "H:|-" + lineFragmentPadding + "-[PlaceholderLabel]-" + lineFragmentPadding + "-|",
                0, new NSDictionary(),
                NSDictionary.FromObjectsAndKeys(
                    new NSObject[] { placeholderLabel }, new NSObject[] { new NSString("PlaceholderLabel") })
            );

            placeholderLabel.TranslatesAutoresizingMaskIntoConstraints = false;

            Control.AddConstraints(hConstraints);
            Control.AddConstraints(vConstraints);
        }
    }
}

 

xaml 코드

콘텐츠 페이지를 만들어 아래와 같이 코딩합니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Test.Controls"
             x:Class="Test.TestPage" BackgroundColor="#253570">
    <ContentPage.Content>
            <StackLayout>
                    <controls:CustomEditor x:Name="customEditor" Margin="7,0,7,0"
                                       BackgroundColor="#DEDFE4" FontSize="15"
                                       IsExpandable="true" Placeholder = "내용(30자이내)" PlaceholderColor="Blue"
                                       MaxLength="30" />
            </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

결과

PlaceholderColor="SlateGray"

 

728x90
Posted by kjun.kr
,