如何创建可编辑的微调器(选取器)?

时间:2016-02-20 10:55:43

标签: c# android xamarin xamarin.forms

我想创建一个可编辑的Spinner(或者Xamarin.Forms中的Picker)。 我有一个自定义渲染器用于我的元素(从Picker派生),它将Picker渲染为AutoCompleteTextView。在渲染器内部,我创建了AutoCompleteTextView,它显示了焦点或点击时的下拉菜单。它工作得很好。

我的问题是它在设备上显示的类似于EditText(或Xamarin.Forms中的Entry)控件,但我想将其显示为Spinner(或者Xamarin.Forms上的Picker)。

知道我怎么做这个吗?

修改 在这里我在UWP做什么: 用于UWP控制的自定义渲染器:

    CustomEditablePicker customControl; // Derived from Xamarin.Forms.Picker
    ComboBox nativeControl; // Windows.UI.Xaml.Controls.ComboBox 
    TextBox editControl;
    protected override void OnElementChanged(ElementChangedEventArgs<CustomEditablePicker> e)
    {
        base.OnElementChanged(e);

        customControl = e.NewElement;

        nativeControl = new ComboBox();

        editControl = new TextBox(); // First element of CheckBox would be a TextBox for edit some Text
        // Set the style (declarated in App.xaml)
        Style editableStyle = App.Current.Resources["ComboBoxItemTextBox"] as Style;

        if (editableStyle != null)
        {
            editControl.Style = editableStyle;

            ComboBoxItem item = new ComboBoxItem();
            item.IsSelected = true;         // Select First element
            item.Content = editControl;     // TextBox as content for first element

            nativeControl.Items.Add(item);
            nativeControl.SelectionChanged += NativeControl_SelectionChanged; // Do something if selection is changed

        }

        // Add items from custom element to native element
        foreach (var item in customControl.Items)
        {

            nativeControl.Items.Add(item);
        }

        editControl.KeyDown += EditControl_KeyDown; // Handle the space key
        editControl.TextChanged += EditControl_TextChanged; // Handle something if text inside TextBox is changed
        base.SetNativeControl(nativeControl); // Set native control to be displayed

    }


    /// <summary>
    /// Set text for Picker if value is changed 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void EditControl_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox edit = (sender as TextBox);
        customControl.Text = edit.Text;
    }


    /// <summary>
    /// Handle Space-Key, without handle this key the ComboBox would be lost focus
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void EditControl_KeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (e.Key == Windows.System.VirtualKey.Space)
        {
            if (editControl.SelectionLength > 0)
            {
                editControl.Text = editControl.Text.Remove(editControl.SelectionStart, editControl.SelectionLength);
                editControl.SelectionLength = 0;
            }
            int pos = editControl.SelectionStart;
            editControl.Text = editControl.Text.Insert(pos, " ");
            editControl.SelectionStart = pos + 1;
            e.Handled = true;
        }
    }


    /// <summary>
    /// Occurs when selection of the box is changed
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void NativeControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count == 1 && e.AddedItems[0] != (sender as ComboBox).Items[0])
        {
            (sender as ComboBox).SelectedIndex = 0;
            editControl.Text = e.AddedItems[0] as String;

        }
    }

PCL中的控件(Xamarin.Forms):

 public class CustomEditablePicker : Picker
{
    public static readonly BindableProperty EditTextProperty = BindableProperty.Create<CustomEditablePicker, string>(c => c.Text, String.Empty, BindingMode.TwoWay, propertyChanged: OnTextChanged);
    public event EventHandler<CustomUIEventArgs<string>> TextChanged;

    public static readonly BindableProperty Source = BindableProperty.Create<CustomEditablePicker, IEnumerable<string>>(l => l.ItemsSource, new List<string>(), BindingMode.TwoWay, propertyChanged: OnSourceChanged);

    private static void OnSourceChanged(BindableObject bindable, IEnumerable<string> oldValue, IEnumerable<string> newValue)
    {
        CustomEditablePicker customEditablePicker = (CustomEditablePicker)bindable;
        customEditablePicker.ItemsSource = newValue;
    }


    public event EventHandler<CustomUIEnumerableArgs<IEnumerable<string>>> SourceChanged;




    public IEnumerable<string> ItemsSource
    {
        get { return (List<string>)this.GetValue(Source); }

        set
        {
            if (this.ItemsSource != value)
            {
                this.SetValue(Source, value);
                if (SourceChanged != null)
                {
                    this.SourceChanged.Invoke(this, new CustomUIEnumerableArgs<IEnumerable<string>>(value));
                }
            }
        }
    }

    public string Text
    {
        get { return (string)this.GetValue(EditTextProperty); }
        set
        {
            if (this.Text != value)
            {
                this.SetValue(EditTextProperty, value);
                if (TextChanged != null)
                {
                    // Raise a event, with changed text
                    this.TextChanged.Invoke(this, new CustomUIEventArgs<string>(value));
                }
            }
        }
    }


    private static void OnTextChanged(BindableObject bindable, string oldValue, string newValue)
    {
        CustomEditablePicker customEditablePicker = (CustomEditablePicker)bindable;
        customEditablePicker.Text = newValue;
    }
}

1 个答案:

答案 0 :(得分:1)

要在EditText中显示图片,请使用SetCompoundDrawablesWithIntrinsicBounds

    protected override void OnElementChanged(ElementChangedEventArgs<SoundsPicker> e)
    {
        if (e.NewElement != null)
        {
            if (base.Control == null)
            {
                EditText editText = new EditText(Context)
                {
                    Focusable = false,
                    Clickable = true,
                    Tag = this
                };

                var padding = (int)Context.ToPixels(10);
                // that show image on right side
                editText.SetCompoundDrawablesWithIntrinsicBounds(0, 0, Resource.Drawable.arrow_down, 0);
                editText.CompoundDrawablePadding = padding;
                editText.SetOnClickListener(MyPickerPickerListener.Instance);
                editText.SetBackgroundDrawable(null);
                SetNativeControl(editText);
            }
        }
        base.OnElementChanged(e);
    }

Resource.Drawable.arrow_down在哪里是您的箭头图片。

您可以使用ILSpy或dotPeek等工具查看Xamarin程序集中的代码。