当它获得焦点时,我无法让选择器发出信号。
我正在尝试获取一个过滤列表,以通过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...
}
}
答案 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");
}
}
}