那么如何使用 MVVM 模式将文本框聚焦在按钮单击上?
我创建了一个简单的基于 this Answer 的测试项目,它在第一次点击时工作,但之后它不再设置焦点。我想念什么?
XAML( View )
<Grid>
<TextBox Height='23' HorizontalAlignment='Left' Margin='12,12,0,0' VerticalAlignment='Top' Width='120'
Text='{Binding TheText}'
local:FocusExtension.IsFocused="{Binding IsFocused}"/>
<Button Content='Click' Height='23' HorizontalAlignment='Left' Margin='138,11,0,0' VerticalAlignment='Top' Width='75'
Command='{Binding ClickCommand}'/>
<Button Content='Just to deFocus' Height='28' HorizontalAlignment='Left' Margin='14,44,0,0' Name='button1' VerticalAlignment='Top' Width='199' />
</Grid>
View 模型
public class ViewModel : INotifyPropertyChanged
{
public string TheText { get; set; }
public bool IsFocused { get; set; }
private RelayCommand _clickCommand;
public ICommand ClickCommand
{
get { return _clickCommand ?? (_clickCommand = new RelayCommand(param => this.OnClick())); }
}
private void OnClick()
{
IsFocused = true;
RaisePropertyChanged("IsFocused");
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
#endregion
}
这是一个 Download link,为懒惰的人准备好了项目(VS2010);)
最佳答案
在覆盖初始默认值后,您的附加属性值永远不会返回 false。因此,您的 FocusExtension
类不会在 Focus()
上调用 TextBox
,因为在将 VM 中的 PropertyChanged
设置为 true 时不需要触发 IsFocused
。
切换 OnIsFocusedPropertyChanged(...)
从:
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
uie.Focus(); // Don't care about false values.
}
至
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var uie = (UIElement)d;
if (!((bool)e.NewValue))
return;
uie.Focus();
uie.LostFocus += UieOnLostFocus;
}
private static void UieOnLostFocus(object sender, RoutedEventArgs routedEventArgs) {
var uie = sender as UIElement;
if (uie == null)
return;
uie.LostFocus -= UieOnLostFocus;
uie.SetValue(IsFocusedProperty, false);
}
更新:
随着上述变化也确保
local:FocusExtension.IsFocused="{Binding IsFocused}"
切换到
local:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"
Working Download Link
另一个更新
在
Mode=TwoWay
类开关中将 FocusExtension
设置为此附加属性的默认值public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new UIPropertyMetadata(
false,
OnIsFocusedPropertyChanged));
至
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnIsFocusedPropertyChanged));
您可以使用上述声明跳过在 xaml 中显式指定
Mode=TwoWay
的步骤。关于c# - 如何将文本框聚焦在按钮单击上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16964886/