在 Validation.HasError 上以 WPF MVVM 方式将焦点设置到 UI 控件
Setting focus to UI control in WPF MVVM Way on Validation.HasError
问题:Validation.HasError 通过 INotifyDataErrorInfo 实现自动突出显示有错误的控件。
我的问题是当它出现错误时我需要将注意力集中在那个特定的控件上。
我该怎么做?
我已经浏览了 Whosebug 和其他网站上的几篇文章,我终于想解决这个问题。
<Style TargetType="TextBox" >
<Setter Property="OverridesDefaultStyle" Value="false"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,3" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
设置 FocusedElement 就可以了。 :)
这也可以用于通过 DataTrigger 在 ViewModel 中使用布尔值 属性 来设置焦点,而不是简单的触发器。
Wpf MVVM 使用 FocusExtension 行为
public static class FocusExtension
{
public static bool GetIsFocused(DependencyObject obj)
{
return (bool)obj.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject obj, bool value)
{
obj.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached(
"IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Focus();
}
}
}
Xaml代码
<TextBox
behavior:FocusExtension.IsFocused="{Binding NameFocus}"
Text="{Binding Customer_Name,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"
x:Name="txtname"
CharacterCasing="Upper"
Grid.Column="3"
Grid.Row="1"
TextWrapping="Wrap"
BorderThickness="1,1,1,0.5"
>
</TextBox>
视图模型中的 MVVM 属性
public const string NameFocusPropertyName = "NameFocus";
private bool _NameFocus = default(bool);
public bool NameFocus
{
get
{
return _NameFocus;
}
set
{
if (_NameFocus == value)
{
return;
}
_NameFocus = value;
RaisePropertyChanged(NameFocusPropertyName);
}
}
设置加载事件
NameFocus=true
问题:Validation.HasError 通过 INotifyDataErrorInfo 实现自动突出显示有错误的控件。
我的问题是当它出现错误时我需要将注意力集中在那个特定的控件上。
我该怎么做?
我已经浏览了 Whosebug 和其他网站上的几篇文章,我终于想解决这个问题。
<Style TargetType="TextBox" >
<Setter Property="OverridesDefaultStyle" Value="false"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,3" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
设置 FocusedElement 就可以了。 :) 这也可以用于通过 DataTrigger 在 ViewModel 中使用布尔值 属性 来设置焦点,而不是简单的触发器。
Wpf MVVM 使用 FocusExtension 行为
public static class FocusExtension
{
public static bool GetIsFocused(DependencyObject obj)
{
return (bool)obj.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject obj, bool value)
{
obj.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached(
"IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Focus();
}
}
}
Xaml代码
<TextBox
behavior:FocusExtension.IsFocused="{Binding NameFocus}"
Text="{Binding Customer_Name,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"
x:Name="txtname"
CharacterCasing="Upper"
Grid.Column="3"
Grid.Row="1"
TextWrapping="Wrap"
BorderThickness="1,1,1,0.5"
>
</TextBox>
视图模型中的 MVVM 属性
public const string NameFocusPropertyName = "NameFocus";
private bool _NameFocus = default(bool);
public bool NameFocus
{
get
{
return _NameFocus;
}
set
{
if (_NameFocus == value)
{
return;
}
_NameFocus = value;
RaisePropertyChanged(NameFocusPropertyName);
}
}
设置加载事件
NameFocus=true