我想创建一个可编辑的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;
}
}
答案 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程序集中的代码。