none
WPF 设置TabIndex无效 RRS feed

  • 问题

  • 我自定义一个Button,如下:

    <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="IsTabStop" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Grid Width="auto" Height="auto">
                                <Image x:Name="image" Margin="0,0,0,0" Source="{Binding ElementName=UserControl2,Path=ImgIsNormal}"/>
           <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextElement.Foreground="Black" TextElement.FontSize="14" TextElement.FontFamily="SegoeUI" Content="{Binding ElementName=UserControl2,Path=ImgString}"/>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding ElementName=UserControl2,Path=ImgIsMouseOver}"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding ElementName=UserControl2,Path=ImgIsPressed}"/>
                                </Trigger>
                                <Trigger Property="IsFocused" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding ElementName=UserControl2,Path=ImgIsMouseOver}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    TabIndex设置无效,还有用Keyboard.Focus(buttonName)无法让button获取焦点,这是什么原因,是不是要在自定义的button中做些处理,请指教

    2012年8月31日 3:39

答案

  • 这是一个简单的例子:

    ImageButton.cs

        public class ImageButton : Button
        {
            public static readonly DependencyProperty ImageSourceProperty =
                DependencyProperty.Register("ImageSource", typeof(String), typeof(Button));
            public static readonly DependencyProperty FocusedImageSourceProperty =
                DependencyProperty.Register("FocusedImageSource", typeof(String), typeof(Button));
            public static readonly DependencyProperty PressedImageSourceProperty =
                DependencyProperty.Register("PressedImageSource", typeof(String), typeof(Button));
    
            public string ImageSource {
                set { SetValue(ImageSourceProperty, value); }
                get { return (string)GetValue(ImageSourceProperty); }
            }
    
            public string FocusedImageSource {
                set { SetValue(FocusedImageSourceProperty, value); }
                get { return (string)GetValue(FocusedImageSourceProperty); }
            }
    
            public string PressedImageSource {
                set { SetValue(PressedImageSourceProperty, value); }
                get { return (string)GetValue(PressedImageSourceProperty); }
            }
        }

    在Resources中声明样式:

            <Style TargetType="local:ImageButton">
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="BorderThickness" Value="0" />
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="IsTabStop" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="local:ImageButton">
                            <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                                <Grid>
                                    <Image Name="image" Margin="0 0 0 0" Source="{Binding Path=ImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}" />
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextElement.FontFamily="Courier New" TextElement.FontSize="14" />
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=FocusedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=PressedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                                <Trigger Property="IsFocused" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=FocusedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    和正常Button一样使用:

                <local:ImageButton Grid.Row="0" Content="Cancel" ImageSource="/Resources/button_n.png" FocusedImageSource="/Resources/button_o.png" PressedImageSource="/Resources/button_p.png" Click="ImageButton_Click" />




    Wanpeng wanpeng.ones@gmail.com

    2012年9月3日 6:19

全部回复

  • 关于Keyboard.Focus你可以看下这个简介:

    http://msdn.microsoft.com/en-us/library/aa969768.aspx

    里面有关于Keyboard Focus的说明,推荐在Loaded事件中使用Keyboard.Focus.

    你的TabIndex设置无效指的是什么?


    Wanpeng wanpeng.ones@gmail.com

    2012年8月31日 6:00
  • 比如有两个button,按tab键可以从第一个跳到第二个,但是设置tabindex不能更改他们的顺序,没效果
    2012年8月31日 6:54
  • 我不能重现你的问题,所以这个你需要自己解决,你可以看一下当前从第一个Button按下Tab后跳转到什么控件,然后逐个排查问题。

    你的问题可能出在容器上,对于每个包裹控件的容器,你检查一下,该容器的TabIndex也是需要的。


    Wanpeng wanpeng.ones@gmail.com

    2012年8月31日 7:16
  • 你的代码发出来看下,我这边button就放在stackpanel中,但是stackpanel中没有tabindex属性

    2012年8月31日 8:34
  • 我的代码说明不了任何问题,也没有任何意义。还是你把你的代码发出来吧,如果你不介意,可以把项目放在SkyDrive中,我帮你看看。


    Wanpeng wanpeng.ones@gmail.com

    2012年8月31日 8:53
  • http://l6.yunpan.cn/lk/19ynmrrxvn你下来看看
    2012年9月1日 2:05
  • 你好,我看了你的代码,你可以使用下面的样式声明。

        <Window.Resources>
            <Style TargetType="controls:myButton">
                <Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
            </Style>
        </Window.Resources>
    关于KeyboardNavigation.TabNavigation在我之前给出的链接里也有,你可以详细看一下。

    Wanpeng wanpeng.ones@gmail.com

    2012年9月3日 2:04
  • 还有就是我发现,当按钮获得焦点时,不能响应回车键。属性设置的时候没有IsDefault这个属性

    2012年9月3日 3:50
  • 使用Button.Click,而非Click捕获事件。

    事实上你的UserControl应当直接继承Button控件,然后声明一些属性和路由并赋予特定的样式,而不是现在这种形式。


    Wanpeng wanpeng.ones@gmail.com

    2012年9月3日 5:47
  • 这是一个简单的例子:

    ImageButton.cs

        public class ImageButton : Button
        {
            public static readonly DependencyProperty ImageSourceProperty =
                DependencyProperty.Register("ImageSource", typeof(String), typeof(Button));
            public static readonly DependencyProperty FocusedImageSourceProperty =
                DependencyProperty.Register("FocusedImageSource", typeof(String), typeof(Button));
            public static readonly DependencyProperty PressedImageSourceProperty =
                DependencyProperty.Register("PressedImageSource", typeof(String), typeof(Button));
    
            public string ImageSource {
                set { SetValue(ImageSourceProperty, value); }
                get { return (string)GetValue(ImageSourceProperty); }
            }
    
            public string FocusedImageSource {
                set { SetValue(FocusedImageSourceProperty, value); }
                get { return (string)GetValue(FocusedImageSourceProperty); }
            }
    
            public string PressedImageSource {
                set { SetValue(PressedImageSourceProperty, value); }
                get { return (string)GetValue(PressedImageSourceProperty); }
            }
        }

    在Resources中声明样式:

            <Style TargetType="local:ImageButton">
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="BorderThickness" Value="0" />
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="IsTabStop" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="local:ImageButton">
                            <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                                <Grid>
                                    <Image Name="image" Margin="0 0 0 0" Source="{Binding Path=ImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}" />
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextElement.FontFamily="Courier New" TextElement.FontSize="14" />
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=FocusedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=PressedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                                <Trigger Property="IsFocused" Value="true">
                                    <Setter Property="Source" TargetName="image" Value="{Binding Path=FocusedImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ImageButton}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    和正常Button一样使用:

                <local:ImageButton Grid.Row="0" Content="Cancel" ImageSource="/Resources/button_n.png" FocusedImageSource="/Resources/button_o.png" PressedImageSource="/Resources/button_p.png" Click="ImageButton_Click" />




    Wanpeng wanpeng.ones@gmail.com

    2012年9月3日 6:19