那么如何使用MVVM模式关注按钮上的TextBox?
我创建了一个简单的测试项目基于这个答案,它在第一次点击时起作用,但之后它不再设置焦点.我错过了什么?
XAML(查看)
<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>
Run Code Online (Sandbox Code Playgroud)
视图模型
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
}
Run Code Online (Sandbox Code Playgroud)
这是一个下载链接,带有准备好的项目(VS2010),适用于懒人;)
在覆盖初始默认值后,您的附加属性值永远不会返回false.因此,当您在VM中设置为true 时,您的FocusExtension类不会调用Focus(),TextBox因为PropertyChanged不需要触发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.
}
Run Code Online (Sandbox Code Playgroud)
至
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);
}
Run Code Online (Sandbox Code Playgroud)
更新:
随着上述变化也确定
local:FocusExtension.IsFocused="{Binding IsFocused}"
切换到
local:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"
另一个更新
Mode=TwoWay在FocusExtension类开关中为此附加属性设置默认值
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new UIPropertyMetadata(
false,
OnIsFocusedPropertyChanged));
Run Code Online (Sandbox Code Playgroud)
至
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnIsFocusedPropertyChanged));
Run Code Online (Sandbox Code Playgroud)
您可以跳过Mode=TwoWay使用上述声明在xaml中明确指定.