gpt4 book ai didi

silverlight - 选择 TabItem 时将焦点设置到 TabItem 中的 TextBox

转载 作者:行者123 更新时间:2023-12-04 03:19:05 26 4
gpt4 key购买 nike

我有一个 Silverlight 应用程序,它有一个带有多个 TabItem 的 TabControl。当用户选择选项卡项时,我想将焦点设置到该选项卡项中的特定控件。我该怎么做?

我尝试为 TabControl 的 SelectionChanged 事件创建一个事件处理程序,并添加以下代码:

private void tcTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (tcTabs != null)
{
switch (tcTabs.SelectedIndex)
{
case 0:
txtTextBox1.Focus();
break;

case 1:
txtTextBox2.Focus();
break;

...
}
}
}

其中 txtTextBox1txtTextBox2 是相关选项卡中的 TextBox 控件。

如果我在 Focus 方法调用上设置断点,当我从一个选项卡切换到另一个选项卡时,我会看到它们被调用,但当选项卡显示时控件并未聚焦。我的假设是我需要在稍后的某个时刻调用 Focus,但我不知道何时调用它或如何调用它。

非常感谢任何帮助。

谢谢

最佳答案

TabControl 的有趣事实:每次切换选项卡时,TabItem 的子控件都会重新加载。也就是说,引发其 Loaded 事件。因此您可以在那里附加一个事件。

也就是说,我更喜欢使用 Expression SDK 中提供的触发器/操作行为,这样我就可以通过 XAML 将所有这些连接起来(对我来说,这比每次需要时都必须附加事件更具可重用性)。

如果您还没有 System.Windows.Interactivity.dll,请添加对它的引用。

使用此触发操作子类:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace SilverlightApplication1 {
public class SetFocusAction : TriggerAction<DependencyObject> {
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register( "Target", typeof( Control ), typeof( SetFocusAction ), new PropertyMetadata( null ) );

public Control Target {
get { return (Control) GetValue( TargetProperty ); }
set { SetValue( TargetProperty, value ); }
}

protected override void Invoke( object parameter ) {
if( Target != null ) {
Target.Focus();
}
}
}
}

然后像这样连接起来:

<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:SilverlightApplication1">
<Grid x:Name="LayoutRoot">
<sdk:TabControl>
<sdk:TabItem Header="Tab 1">
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<local:SetFocusAction Target="{Binding ElementName=tb1}"></local:SetFocusAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBox Width="200" Height="30" x:Name="tb1"></TextBox>
</Grid>
</sdk:TabItem>
<sdk:TabItem Header="Tab 2">
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<local:SetFocusAction Target="{Binding ElementName=tb2}"></local:SetFocusAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBox Width="200" Height="30" x:Name="tb2"></TextBox>
</Grid>
</sdk:TabItem>
</sdk:TabControl>
</Grid>
</UserControl>

请注意,当您第一次运行包含此内容的应用程序时,Silverlight 对象本身可能没有焦点,因此您必须连接 javascript 来手动聚焦它。但是,一旦用户单击 Silverlight 应用程序(或您的 javascript 设置焦点),此操作就会完成其工作。

为了好玩,这里有一个完整的Behavior子类,它将与DataForm一起使用,并且应该适用于其他模板化控件。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace SilverlightApplication1 {
public class SetFocusBehavior : Behavior<FrameworkElement> {
public static readonly DependencyProperty TargetNameProperty =
DependencyProperty.Register( "TargetName", typeof( string ), typeof( SetFocusBehavior ), new PropertyMetadata( null ) );

private bool _setFocusOnLayoutUpdated;

public string TargetName {
get { return (string) GetValue( TargetNameProperty ); }
set { SetValue( TargetNameProperty, value ); }
}

protected override void OnAttached() {
base.OnAttached();

this.AssociatedObject.LayoutUpdated += new EventHandler( AssociatedObject_LayoutUpdated );
this.AssociatedObject.Loaded += new RoutedEventHandler( AssociatedObject_Loaded );
}

protected override void OnDetaching() {
base.OnDetaching();

this.AssociatedObject.LayoutUpdated -= new EventHandler( AssociatedObject_LayoutUpdated );
this.AssociatedObject.Loaded -= new RoutedEventHandler( AssociatedObject_Loaded );
}

private void AssociatedObject_Loaded( object sender, RoutedEventArgs e ) {
if( !FindAndSetFocus() ) {
_setFocusOnLayoutUpdated = true;
}
}

private void AssociatedObject_LayoutUpdated( object sender, EventArgs e ) {
if( _setFocusOnLayoutUpdated ) {
_setFocusOnLayoutUpdated = false;
FindAndSetFocus();
}
}

private bool FindAndSetFocus() {
var found = Find( this.AssociatedObject ) as Control;
if( found != null ) {
found.Focus();

return true;
}

return false;
}

private DependencyObject Find( DependencyObject root ) {
if( root != null ) {
if( (string) root.GetValue( FrameworkElement.NameProperty ) == TargetName ) {
return root;
}

for( int i = 0; i < VisualTreeHelper.GetChildrenCount( root ); i++ ) {
var result = Find( VisualTreeHelper.GetChild( root, i ) );
if( result != null )
return result;
}
}
return null;
}
}
}

和 XAML:

<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:tk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:local="clr-namespace:SilverlightApplication1">
<Grid x:Name="LayoutRoot">
<sdk:TabControl>
<sdk:TabItem Header="Tab 1">
<Grid>
<i:Interaction.Behaviors>
<local:SetFocusBehavior TargetName="tb1"></local:SetFocusBehavior>
</i:Interaction.Behaviors>
<TextBox Width="200" Height="30" x:Name="tb1"></TextBox>
</Grid>
</sdk:TabItem>
<sdk:TabItem Header="Tab 2">
<Grid>
<i:Interaction.Behaviors>
<local:SetFocusBehavior TargetName="tb2"></local:SetFocusBehavior>
</i:Interaction.Behaviors>
<tk:DataForm CurrentItem="sometext">
<tk:DataForm.EditTemplate>
<DataTemplate>
<TextBox Width="200" Height="30" x:Name="tb2"></TextBox>
</DataTemplate>
</tk:DataForm.EditTemplate>
</tk:DataForm>
</Grid>
</sdk:TabItem>
</sdk:TabControl>
</Grid>
</UserControl>

关于silverlight - 选择 TabItem 时将焦点设置到 TabItem 中的 TextBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6823830/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com