我有一个Xamarin.Forms ListView,它有一个自定义ViewCell,其中包含一个带有条目和标签的StackLayout。我希望在ViewCell被选中的任何时候,条目都能获得焦点。
ItemSelected提供所选的项,但不提供ViewCell。我可以为ViewCell创建一个自定义类,但是我看不出它是如何知道何时被选中的。
如何将条目集中在ListView项选择上?
发布于 2018-04-06 03:16:01
将条目移动到视图模型中,并将条目绑定到ViewCell中的一个ViewCell。在ListView.ItemSelected事件处理程序中,SelectedItem现在包含可以调用Focus的条目。
XAML如下所示:(在本例中,条目包含一个数量。)
<ViewCell>
<StackLayout Orientation="Horizontal">
<ContentView Content="{Binding QuantityView}" />
<Label ... />
</StackLayout>
</ViewCell>视图模型如下所示:
public class MyViewModel {
public string Quantity {get; set;}
public Entry QuantityView { get; } = new Entry {...};
public MyViewModel() {
QuantityView.SetBinding(Entry.TextProperty, nameof(Quantity));
}
}ItemSelected事件处理程序如下所示:
void FocusQuantity(object sender, SelectedItemChangedEventArgs e) {
if (e.SelectedItem == null) return;
((MyViewModel)e.SelectedItem).QuantityView.Focus();
}发布于 2018-03-13 05:23:28
我这样做的方式是创建一个类- Viewholder它保存了您想要的2个视图。然后将其用于ListView ItemSource,并将重点放在SelectedItem属性更改上。
Viewholder:
public class Viewholder
{
public Viewholder (){
}
public void OnFocus(){
Entry.Focus();
}
private Entry _entry ;
public Entry Entry{
get { return _entry;}
set{
if (value != null &&
_entry!= value){
_entry= value;
OnPropertyChanged();
}
}
private Label _label
public Label Label{
get { return _label;}
set{
if (value != null &&
_label!= value) {
_label= value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null){
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}MainPage (ListView父母):
public class MainPage : ContentPage
{
public MainPage () {
SetUpControls();
}
private ObservableCollection<ViewHolder> _viewHolders;
public ObservableCollection<ViewHolder> ViewHolders
{
get { return _viewHolders;}
set{
if (value != null &&
_viewHolders!= value){
_viewHolders= value;
OnPropertyChanged();
}
}
private ViewHolder _selectedViewHolder;
public ViewHolder SelectedViewHolder{
get { return _selectedViewHolder;}
set{
if (value != null &&
_selectedViewHolder != value){
_selectedViewHolder= value;
OnPropertyChanged();
_selectedViewHolder.OnFocus();
}
}
private void SetUpControls(List<string> l){
foreach(var s in l){
ViewHolder v = new ViewHolder{
Label = new Label{
Text = s,
};
Entry = new Entry();
};
ViewHolders.Add(v);
}
if(l.Count > 0){
SelectedViewHolder = ViewHolders.ElementAt(0);
}
}
}XAML:
<ListView ItemsSource="{Binding ViewHolders, Mode=TwoWay}"
SelectedItem="{Binding SelectedViewHolder, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Content="{Binding Label, Mode="TwoWay"}/>
<ContentView Content="{Binding Entry, Mode="TwoWay"}/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>这不是最好的选择,但对我有效。
另外,如果添加通过直接聚焦于条目而触发的OnSelection事件,则可以将SelectedItem设置为包含条目的ViewHolder。但是这是非常丑陋的代码(当你看到我在上面做了什么的时候,这就说明了一些问题!)涉及到寻找控制父(和父母),直到父控件是列表视图(使控件成为一个视图单元格),并为其设置焦点。
https://stackoverflow.com/questions/48811089
复制相似问题