问题
I have a custom textbox control that displays its name when there is no text inside of it, but for some curious reason I have to hit tab twice to get from the previous element to get into the control's text field. On the first tab it highlight's the TextBox's border. I went through all of the levels of the Generic.xaml file with the properties window open and searching for 'tab' but the only one that I could find was on the TextBox itself which is properly tabstopping. How do I make my control only take one tab to get into the
Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SuperTB">
<Style TargetType="{x:Type local:SuperTextB}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SuperTextB}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=LostFocus }" x:Name="PART_input">
</TextBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CS:
[TemplatePart(Name="PART_input")]
public class SuperTextB : Control
{
private TextBox PART_input;
static SuperTextB()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SuperTextB), new FrameworkPropertyMetadata(typeof(SuperTextB)));
}
public SuperTextB()
{
Loaded += SuperTextBLoaded;
}
void SuperTextBLoaded(object sender, RoutedEventArgs e)
{
if (PART_input.Text == string.Empty)
{
PART_input.Background = convertName();
}
}
public override void OnApplyTemplate()
{
PART_input = GetTemplateChild("PART_input") as TextBox;
if (PART_input != null)
{
PART_input.GotFocus += PartInputGotFocus;
PART_input.LostFocus += PartInputLostFocus;
}
}
void PartInputLostFocus(object sender, RoutedEventArgs e)
{
if (PART_input.Text == string.Empty)
{
PART_input.Background = convertName();
}
}
private VisualBrush convertName()
{
char[] pieces = Name.ToCharArray();
for (int x = 0; x < pieces.Length; x++)
{
if (pieces[x].Equals('_'))
pieces[x] = ' ';
}
String toReturn = "";
foreach (char c in pieces)
toReturn += c.ToString();
VisualBrush myVis = new VisualBrush();
myVis.Stretch = Stretch.None;
TextBlock myText = new TextBlock();
myText.Text = toReturn;
myText.Foreground=Brushes.Gray;
myVis.Visual=myText;
return myVis;
}
void PartInputGotFocus(object sender, RoutedEventArgs e)
{
PART_input.Background = Brushes.White;
}
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(String), typeof(SuperTextB));
public string Text
{
get { return (String)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
}
}
回答1:
It's because you have a TextBox
within the template for your TextBox
. That TextBox
is focusable, as is your outer TextBox
. Set IsFocusable
to False
or alter your template such that it doesn't include a TextBox
within it.
回答2:
simply put <Setter Property="Focusable" Value="False"/>
in between <Style TargetType="{x:Type local:SuperTextB}">
<Setter Property="Template">
will fix it.
来源:https://stackoverflow.com/questions/6538364/wpf-custom-textbox-takes-two-tabs-to-get-to-text