Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight 选择TabItem时,将焦点设置为TabItem中的文本框_Silverlight_Focus - Fatal编程技术网

Silverlight 选择TabItem时,将焦点设置为TabItem中的文本框

Silverlight 选择TabItem时,将焦点设置为TabItem中的文本框,silverlight,focus,Silverlight,Focus,我有一个Silverlight应用程序,它有一个带有多个TabItems的TabControl。当用户选择选项卡项时,我希望将焦点设置为该选项卡项中的特定控件。我该怎么做 我尝试为TabControl的SelectionChanged事件创建事件处理程序,并添加了以下代码: private void tcTabs_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (tcTabs != null) {

我有一个Silverlight应用程序,它有一个带有多个TabItems的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;

            ...
        }
    }
}
其中
txtextbox1
txtextbox2
是相关选项卡中的文本框控件

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

非常感谢您的帮助


感谢TabControl的有趣之处:每次切换选项卡时,都会再次加载TabItem的子控件。也就是说,将引发其加载的事件。因此,您可以将事件附加到那里

也就是说,我的首选是使用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();
            }
        }
    }
}
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Interactive;
命名空间SilverlightApplication1{
公共类SetFocusAction:TriggerAction{
公共静态只读DependencyProperty TargetProperty=
Register(“Target”、typeof(Control)、typeof(SetFocusAction)、newpropertyMetadata(null));
公共控制目标{
获取{return(Control)GetValue(TargetProperty);}
set{SetValue(TargetProperty,value);}
}
受保护的覆盖无效调用(对象参数){
如果(目标!=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设置焦点),此操作将完成其工作

有趣的是,这里有一个完整的行为子类,它将与数据表单一起工作,并且应该与其他模板化控件一起工作

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;
        }
    }
}
使用系统;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Interactive;
使用System.Windows.Media;
命名空间SilverlightApplication1{
公共类SetFocusBehavior:行为{
公共静态只读DependencyProperty TargetNameProperty=
Register(“TargetName”、typeof(string)、typeof(SetFocusBehavior)、newpropertyMetadata(null));
私人bool_setFocusOnLayoutUpdated;
公共字符串TargetName{
获取{return(string)GetValue(TargetNameProperty);}
set{SetValue(TargetNameProperty,value);}
}
受保护的覆盖无效附加(){
base.onatached();
this.AssociatedObject.LayoutUpdated+=新事件处理程序(AssociatedObject\u LayoutUpdated);
this.AssociatedObject.Loaded+=新路由EventHandler(AssociatedObject\u Loaded);
}
附加时受保护的覆盖无效(){
base.OnDetaching();
this.AssociatedObject.LayoutUpdated-=新事件处理程序(AssociatedObject\u LayoutUpdated);
this.AssociatedObject.Loaded-=新路由EventHandler(AssociatedObject\u Loaded);
}
已加载关联对象的私有无效(对象发送方,路由目标){
如果(!FindAndSetFocus()){
_setFocusOnLayoutUpdated=true;
}
}
私有无效关联对象\u布局已更新(对象发送方,事件参数e){
如果(_setFocusOnLayoutUpdated){
_setFocusOnLayoutUpdated=false;
FindAndSetFocus();
}
}
私有布尔FindAndSetFocus(){
var found=Find(this.AssociatedObject)作为控件;
如果(找到!=null){
found.Focus();
返回true;
}
返回false;
}
私有DependencyObject查找(DependencyObject根){
if(root!=null){
if((字符串)root.GetValue(FrameworkElement.NameProperty)==TargetName){
返回根;
}
for(int i=0;i
以及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>