在 wpf 中将焦点转移到控件的子部分(在其模板中)
我有一个文本框,在某些情况下需要“转换”为 DatePicker。
使用模板轻松完成:
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="local:MyTextBox.IsDate" Value="True">
<Setter Property="Template" Value="{StaticResource DateTextBoxTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
然后:
<ControlTemplate x:Key="DateTextBoxTemplate" TargetType="TextBox">
<DatePicker x:Name="DateContent"
Text="{Binding RelativeSource={RelativeSource AncestorType=TextBox}, Path=Text, Mode=TwoWay}" />
</ControlTemplate>
问题是:当我单击日期选择器时,焦点没有“转移”到日期选择器。
即:如果我单击控件,datePicker 不会获得焦点。我必须再次单击它才能发生这种情况。
我知道我可以在后面的代码中执行此操作:
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (IsDate)
{
DatePicker dateContent = Template.FindName("DateContent", this) as DatePicker;
if (dateContent != null) dateContent.Focus();
}
}
但这并不能真正令我满意,因为我很确定有一种方法可以在 xaml 中完成所有操作,但我只是不知道。
我发现另一个问题提到 FocusManager.FocusedElement="{Binding ElementName=DateContent}"
选项,但我不知道可以将这段代码放在哪里:它无法添加到controlTemplate(正如我怀疑的那样),如果我把它放在模板中封装datePicker的网格上,它基本上没有用。
那么我可以只在 xaml 中执行此操作吗?如果是,怎么办?
I have a textBox that needs to be "transformed" into a DatePicker under certain circumstances.
easily done with template:
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="local:MyTextBox.IsDate" Value="True">
<Setter Property="Template" Value="{StaticResource DateTextBoxTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
and then:
<ControlTemplate x:Key="DateTextBoxTemplate" TargetType="TextBox">
<DatePicker x:Name="DateContent"
Text="{Binding RelativeSource={RelativeSource AncestorType=TextBox}, Path=Text, Mode=TwoWay}" />
</ControlTemplate>
the trouble is: the focus is not "transferred" to the datepicker when I click on it.
i.e: if I click on the control, the datePicker does not get the focus. I have to click on it once again for this to happen.
I know I can do in my code behind:
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (IsDate)
{
DatePicker dateContent = Template.FindName("DateContent", this) as DatePicker;
if (dateContent != null) dateContent.Focus();
}
}
but this does not really satisfy me as I'm pretty sure there is a way to do it all in xaml and I just don't know about it.
I found an other question mentioning the FocusManager.FocusedElement="{Binding ElementName=DateContent}"
option, but I have no clue as to where I could put this piece of code: it cannot be added to the controlTemplate (as I suspected), and if I put it on a grid encapsulating the datePicker in the template, it is basically useless.
so can I do this in xaml only? and if yes, how?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我过去用过这个并且很有效
I've used this in the past and it has worked
您可以通过告诉
DatePicker
它在加载时默认获得焦点来实现所需的行为。为此,您可以创建一个附加行为,如下所示:然后您可以设置
IsDefaultFocusElement
附加在DatePicker
上的属性,每次加载DatePicker
时,它都会获得焦点:此行为可以用在您的任何其他地方。您需要指定默认情况下必须聚焦的元素的应用程序(例如,当您打开对话框并且希望立即聚焦第一个字段时)。
You can achieve the desired behavior by telling the
DatePicker
that it should be focused by default when loaded. To do this you can create an Attached Behavior like this:Then you can set the
IsDefaultFocusElement
attached property on theDatePicker
and every time theDatePicker
is loaded it will receive focus:This behavior can be used in any other places in your application where you need to specify an element that has to be focused by default (e.g. when you open a dialog and you want the first field to be focused right away).