MAUI 下拉/选择

问题描述 投票:0回答:1

如何在 MAUI 中创建类似的下拉菜单/选择。有什么可能的例子吗?我只需要为数据验证制作一个工具提示,以便它显示在所有类型元素的顶部,如 HTML 中的position:absolute;。但我在任何地方都找不到类似的东西。我只知道这应该通过自己的控件来完成

在此输入图像描述 在此输入图像描述

我使用第三方控件。而且我不明白他们是如何制作它们的。我想要一个小样本,或者有关如何操作的链接

任何信息和示例

c# .net select drop-down-menu maui
1个回答
0
投票

您可以使用

Listview
和条目创建一个 ComboBox 类。

请参考以下代码:

public class ComboBox : StackLayout
    {
        private Entry _entry;
        private ListView _listView;
        private bool _supressFiltering;
        private bool _supressSelectedItemFiltering;
        //Bindable properties
        public static readonly BindableProperty ListViewHeightRequestProperty = BindableProperty.Create(nameof(ListViewHeightRequest), typeof(double), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._listView.HeightRequest = (double)newVal;
        });
        public double ListViewHeightRequest
        {
            get { return (double)GetValue(ListViewHeightRequestProperty); }
            set { SetValue(ListViewHeightRequestProperty, value); }
        }
        public static readonly BindableProperty EntryBackgroundColorProperty = BindableProperty.Create(nameof(EntryBackgroundColor), typeof(Color), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._entry.BackgroundColor = (Color)newVal;
        });
        public Color EntryBackgroundColor
        {
            get { return (Color)GetValue(EntryBackgroundColorProperty); }
            set { SetValue(EntryBackgroundColorProperty, value); }
        }
        public static readonly BindableProperty EntryFontSizeProperty = BindableProperty.Create(nameof(EntryFontSize), typeof(double), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._entry.FontSize = (double)newVal;
        });
        [TypeConverter(typeof(FontSizeConverter))]
        public double EntryFontSize
        {
            get { return (double)GetValue(EntryFontSizeProperty); }
            set { SetValue(EntryFontSizeProperty, value); }
        }

        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._listView.ItemsSource = (IEnumerable)newVal;
        });
        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
        public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._listView.SelectedItem = newVal;
        });
        public object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }
        public static new readonly BindableProperty VisualProperty = BindableProperty.Create(nameof(Visual), typeof(IVisual), typeof(ComboBox), defaultValue: new DefaultVisual(), propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._listView.Visual = (IVisual)newVal;
            comboBox._entry.Visual = (IVisual)newVal;
        });
        public new IVisual Visual
        {
            get { return (IVisual)GetValue(VisualProperty); }
            set { SetValue(VisualProperty, value); }
        }
        public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(ComboBox), defaultValue: "", propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._entry.Placeholder = (string)newVal;
        });
        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }
        public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(ComboBox), defaultValue: "", propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._entry.Text = (string)newVal;
        });
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(ComboBox), defaultValue: null, propertyChanged: (bindable, oldVal, newVal) => {
            var comboBox = (ComboBox)bindable;
            comboBox._listView.ItemTemplate = (DataTemplate)newVal;
        });
        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }
        public static readonly BindableProperty EntryDisplayPathProperty = BindableProperty.Create(nameof(EntryDisplayPath), typeof(string), typeof(ComboBox), defaultValue: "");
        public string EntryDisplayPath
        {
            get { return (string)GetValue(EntryDisplayPathProperty); }
            set { SetValue(EntryDisplayPathProperty, value); }
        }
        public event EventHandler<SelectedItemChangedEventArgs> SelectedItemChanged;
        protected virtual void OnSelectedItemChanged(SelectedItemChangedEventArgs e)
        {
            EventHandler<SelectedItemChangedEventArgs> handler = SelectedItemChanged;
            handler?.Invoke(this, e);
        }
        public event EventHandler<TextChangedEventArgs> TextChanged;
        protected virtual void OnTextChanged(TextChangedEventArgs e)
        {
            EventHandler<TextChangedEventArgs> handler = TextChanged;
            handler?.Invoke(this, e);
        }
        public ComboBox()
        {
            //Entry used for filtering list view
            _entry = new Entry();
            _entry.Margin = new Thickness(0);
            _entry.Keyboard = Keyboard.Create(KeyboardFlags.None);
            _entry.Focused += (sender, args) => _listView.IsVisible = true;
            _entry.Unfocused += (sender, args) => _listView.IsVisible = false;
            //Text changed event, bring it back to the surface
            _entry.TextChanged += (sender, args) =>
            {
                if (_supressFiltering)
                    return;
                if (String.IsNullOrEmpty(args.NewTextValue))
                {
                    _supressSelectedItemFiltering = true;
                    _listView.SelectedItem = null;
                    _supressSelectedItemFiltering = false;
                }
                _listView.IsVisible = true;
                OnTextChanged(args);
            };
            //List view - used to display search options
            _listView = new ListView();
            _listView.IsVisible = false;
            _listView.Margin = new Thickness(0);
            Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.ListView.SetSeparatorStyle(_listView, Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.SeparatorStyle.FullWidth);
            _listView.HeightRequest = 100;
            _listView.HorizontalOptions = LayoutOptions.StartAndExpand;
            _listView.SetBinding(ListView.SelectedItemProperty, new Binding(nameof(ComboBox.SelectedItem), source: this));
            //Item selected event, surface it back to the top
            _listView.ItemSelected += (sender, args) =>
            {
                if (!_supressSelectedItemFiltering)
                {
                    _supressFiltering = true;
                    var selectedItem = args.SelectedItem;
                    _entry.Text = !String.IsNullOrEmpty(EntryDisplayPath) && selectedItem != null ? selectedItem.GetType().GetProperty(EntryDisplayPath).GetValue(selectedItem, null).ToString() : selectedItem?.ToString();
                    _supressFiltering = false;
                    _listView.IsVisible = false;
                    OnSelectedItemChanged(args);
                    _entry.Unfocus();
                }
            };
            //Add bottom border
            var boxView = new BoxView();
            boxView.HeightRequest = 1;
            boxView.Color = Colors.Black;
            boxView.Margin = new Thickness(0);
            boxView.SetBinding(BoxView.IsVisibleProperty, new Binding(nameof(ListView.IsVisible), source: _listView));
            Children.Add(_entry);
            Children.Add(_listView);
            Children.Add(boxView);
           
        }
        public new bool Focus()
        {
            return _entry.Focus();
        }
        public new void Unfocus()
        {
            _entry.Unfocus();
        }
    }

然后就可以在后面的代码中设置itemsource了:

combobox.ItemsSource = new List<string>() { "item1", "item2", "item3", "item4", "item5","item6" };

并在xaml中使用它:

<local:ComboBox x:Name="combobox"  SelectedItemChanged="combobox_SelectedItemChanged"/>
© www.soinside.com 2019 - 2024. All rights reserved.