【发布时间】:2020-08-26 07:44:21
【问题描述】:
Github repository 重现问题。
我正在使用 Xamarin Forms 来创建应用程序。
<StackLayout>
<Editor x:Name="Editor"
Text="{Binding Text, Mode=TwoWay}">
</Editor>
<Button x:Name="Button"
Text="Complete"
Command="{Binding CompleteCommand}" />
</StackLayout>
当ContentView 可见时,我试图将焦点锁定在Editor。
因此,我使用Editor.Unfocused 事件来锁定焦点,如下所示。
public partial class MyView : ContentView
{
private void OnEditorUnfocused(object sender, FocusEventArgs e)
{
if (IsVisible)
{
Editor.Focus();
}
}
}
当ContentView.IsVisible 属性发生如下变化时,我注册和注销OnEditorUnfocused 方法。
public partial class MyView : ContentView
{
protected override void OnPropertyChanging([CallerMemberName] string propertyName = null)
{
// IsVisible changes from "True" to "False"
if (propertyName.Equals("IsVisible") && IsVisible)
{
Editor.Unfocused -= OnEditorUnfocused;
Editor.Unfocus();
}
base.OnPropertyChanging(propertyName);
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// IsVisible changed from "False" to "True"
if (propertyName.Equals("IsVisible") && IsVisible)
{
Editor.Unfocused += OnEditorUnfocused;
Editor.Focus();
}
base.OnPropertyChanged(propertyName);
}
}
在这里我遇到了一个问题。 Editor.Focus() 和 Editor.Unfocus() 不会立即应用。而当ContentView 不可见时,首先Editor.Focus() 不起作用。此外,当ContentView.Visible 由Button 从True 更改为False 时,键盘仍保留在屏幕上。
因此我像下面这样更改我的代码,
public partial class MyView : ContentView
{
private Task _focusEditorTask;
private Task _unfocusEditorTask;
public event EventHandler LostFocused;
public MyView()
{
InitializeComponent();
_focusEditorTask = _unfocusEditorTask = Task.CompletedTask;
}
private void OnEditorUnfocused(object sender, FocusEventArgs e)
{
if (IsVisible)
{
FocusEditor();
Console.WriteLine($"<Unfocused> Editor: Focused {Editor.IsFocused}");
}
}
private void FocusEditor()
{
_unfocusEditorTask.Wait();
_focusEditorTask.Wait();
_focusEditorTask = Task.Factory.StartNew(async () =>
{
Console.WriteLine($"<FocusEditor> START {Editor.IsFocused}");
while (!Editor.IsFocused)
{
Editor.Focus();
await Task.Delay(100);
Console.WriteLine($"<FocusEditor> PROGRESS {Editor.IsFocused}");
}
Console.WriteLine($"<FocusEditor> END {Editor.IsFocused}");
});
}
private void UnfocusEditor()
{
_focusEditorTask.Wait();
_unfocusEditorTask.Wait();
_unfocusEditorTask = Task.Factory.StartNew(async () =>
{
Console.WriteLine($"<!UnfocusEditor> START {Editor.IsFocused}");
while (Editor.IsFocused)
{
Editor.Unfocus();
await Task.Delay(100);
Console.WriteLine($"<!UnfocusEditor> PROGRESS {Editor.IsFocused}");
}
Console.WriteLine($"<!UnfocusEditor> END {Editor.IsFocused}");
return Task.CompletedTask;
});
}
protected override void OnPropertyChanging([CallerMemberName] string propertyName = null)
{
if (propertyName.Equals("IsVisible") && IsVisible)
{
Console.WriteLine($"<IsVisibleChanging> InputView: IsVisible ({IsVisible}) -> {!IsVisible}");
Editor.Unfocused -= OnEditorUnfocused;
UnfocusEditor();
}
base.OnPropertyChanging(propertyName);
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (propertyName.Equals("IsVisible") && IsVisible)
{
Console.WriteLine($"<IsVisibleChanged> InputView: IsVisible {!IsVisible} -> ({IsVisible})");
Editor.Unfocused += OnEditorUnfocused;
FocusEditor();
}
base.OnPropertyChanged(propertyName);
}
}
现在我只有一个问题,Wait() 无效。
这里是应用程序输出取决于ContnetView.IsVisible的变化,
1。将 ContnetView.IsVisible 从 false 更改为 true
<IsVisibleChanged> InputView: IsVisible False -> (True)
<FocusTextEditor> START False
<FocusTextEditor> PROGRESS False
<FocusTextEditor> PROGRESS True
<FocusTextEditor> END True
2。 Button 将 ContentView.IsVisible 从 true 更改为 false
<Unfocused> TextEditor: Focused False
<FocusTextEditor> START False
<IsVisibleChanging> InputView: IsVisible (True) -> False
// START should not fire...
<!UnfocusTextEditor> START False
<!UnfocusTextEditor> END False
// because of this, keyboard does not disappear even ContnetView is not visible.
<FocusTextEditor> PROGRESS True
<FocusTextEditor> END True
【问题讨论】:
-
Editor.Unfocus()- 如果您将注意力集中在其他控件上会怎样? -
@aepot 不幸的是我已经尝试过了。聚焦
Button不起作用。
标签: c# .net multithreading xamarin xamarin.forms