Picker是否有“重点”事件用作事件触发器?

时间:2018-02-21 14:26:00

标签: c# xamarin.forms

当它获得焦点时,我无法让选择器发出信号。

我正在尝试获取一个过滤列表,以通过MVVM填充Picker(在用户将字符串输入文本框以过滤列表之后)。

我的设置是一个屏幕,其中包含一个可用于输入字符串的文本框(将用于过滤列表)。通过查询本地数据库并将其作为列表返回来填充选择器。起初,我在每次击键时重建该列表(通过重新查询数据库)。这有效,但击键之间的滞后是不可接受的。

我试图不在按键之间建立列表,但只有当文本框失去焦点时才会这样做。最后,通过使用未聚焦的事件触发器告诉VM文本框没有聚焦(通过MessagingCenter完成),能够完成这项工作。此时,我还决定不查询db的列表,而是使用ObservableCollection,认为当OC被过滤时,它会自动更新选择器列表。

这有点(有点),但是如果你在文本框中输入一个字符串,然后点击了选择器,那么在未聚焦的事件被触发之前填充了选择器列表(我认为)。我只是说因为这个名单总是落后一步。换句话说,如果您输入了“ABC”并单击了选择器,则列表中的列表仍然包含所有项目。但是如果你回到文本框并用“XYZ”替换了字符串并再次单击了选择器,则列表中只包含“ABC”的项目。如果您要在文本框中输入一个字符串,请单击任何其他控件(除了选择器),然后然后单击选择器,列表将是正确的。

所以这让我想到,'聚焦'事件可能会在“未聚焦”之前触发,坦率地说,无论如何选择选择器时构建该列表更有意义(因为那是需要它的地方)。但是,当我将触发器移动到选择器控件时,我会在触发事件时出错。构建很好,一切都有效,直到选择器获得控制权,然后崩溃。

FWIW,这是选择器的代码(带触发器):

<!-- (other code) -->
<Picker ItemsSource="{Binding myList}" Title="Select a specification" SelectedItem="{Binding mySelectedItem}" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3">
    <Picker.Triggers>
        <EventTrigger Event="Focused">
            <local:FocusedTriggerAction />
        </EventTrigger>
    </Picker.Triggers>
    <Picker.ItemDisplayBinding>
        <Binding Path="FullName"/>
    </Picker.ItemDisplayBinding>
</Picker>
<!-- (other code) -->

'FocusedTriggerAction'的代码:

namespace DatabaseTest
{
    public class FocusedTriggerAction : TriggerAction<Entry>
    {
        protected override void Invoke(Entry entry)
        {
            MessagingCenter.Send<FocusedTriggerAction>(this, "changeList");
        }
    }
}

虚拟机:

namespace DatabaseTest.ViewModels
{
    public class MyViewModel : INotifyPropertyChanged
    {
        public MyViewModel()
        {
            List<MyOptions> mystuff = new List<MyOptions>();
            using (SQLite.SQLiteConnection conn = new SQLite.SQLiteConnection(App.DB_PATH))
            {
                conn.CreateTable<MyOptions>();
                mystuff = conn.Table<MyOptions>().ToList();
            }
            myList = new ObservableCollection<MyOptions>(mystuff);

            MessagingCenter.Subscribe<FocusedTriggerAction> (this, "changeList", (sender) => 
            {
                if (mylookupstring == "")
                    testme = 1;
                else
                    myList = new ObservableCollection<MyOptions>(mystuff.Where(o => o.SpecFullName.Contains(mylookupstring)));
            });
        }

        string mylookupstring = string.Empty;
        string myselectedthing;
        MyOptions myselectedpickeritem;
        int testme = 0;
        int foundselecteditem = 0;

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged([CallerMemberName] string name = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public string myLookupString
        {
            get { return mylookupstring; }
            set
            {
                mylookupstring = value;
                mylookupstring = mylookupstring.ToUpper();
                OnPropertyChanged();
            }
        }

        private ObservableCollection<MyOptions> _mylist;
        public ObservableCollection<MyOptions> myList
        {
            get { return _mylist; }
            set
            {
                if (_mylist != value)
                {
                    _mylist = value;
                    OnPropertyChanged();
                }
            }
        }
        //...Other code...
    }
}

1 个答案:

答案 0 :(得分:0)

对于可能需要这个问题帮助的其他人,我想出了让Picker正确触发的问题(在这里的同伴的帮助下)。当我将触发器从入口控制器移动到拾取器时,我忘记将代码隐藏中的“入口”部分更改为“选择器”。

我不得不改变这个:

namespace DatabaseTest
{
    public class FocusedTriggerAction : TriggerAction<Entry>
    {
        protected override void Invoke(Entry entry)
        {
            MessagingCenter.Send<FocusedTriggerAction>(this, "changeList");
        }
    }
}

对此:

namespace DatabaseTest
{
    public class FocusedTriggerAction : TriggerAction<Picker>
    {
        protected override void Invoke(Picker sender)
        {
            MessagingCenter.Send<FocusedTriggerAction>(this, "changeList");
        }
    }
}