In einer Anwendung, an der ich arbeite, haben wir eine Reihe von benutzerdefinierten Steuerelementen mit ihren ControlTemplates in Generic.xaml definiert.
Unser benutzerdefiniertes Textfeld würde zum Beispiel so aussehen:
<Style TargetType="{x:Type controls:FieldTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:FieldTextBox}">
<Border BorderThickness="0" Margin="5">
<StackPanel ToolTip="{Binding Path=Field.HintText, RelativeSource={RelativeSource TemplatedParent}}">
<TextBlock Text="{Binding Path=Field.FieldLabel, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Left"
/>
<TextBox Width="{Binding Path=Field.DisplayWidth, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Left"
Text="{Binding Path=Field.Data.CurrentValue, RelativeSource={RelativeSource TemplatedParent}}"
IsEnabled="{Binding Path=Field.IsEnabled, RelativeSource={RelativeSource TemplatedParent}}"
ContextMenu="{Binding Source={StaticResource FieldContextMenu}}" >
<TextBox.Background>
<SolidColorBrush Color="{Binding Path=Field.CurrentBackgroundColor, RelativeSource={RelativeSource TemplatedParent}}"/>
</TextBox.Background>
</TextBox>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Focusable" Value="True" />
<Setter Property="IsTabStop" Value="False" />
</Style>
In unserer Anwendung müssen wir in der Lage sein, den Fokus programmatisch auf ein bestimmtes Steuerelement innerhalb des ControlTemplate zu setzen.
Innerhalb unseres C#-Codes können wir auf der Grundlage unserer Daten die jeweilige "FieldTextBox" aufrufen. Sobald wir die richtige FieldTextBox haben, müssen wir den Fokus auf die tatsächliche TextBox im ControlTemplate setzen können.
Die beste Lösung, die ich gefunden habe, ist ein Name für das primäre Steuerelement in jeder Steuervorlage (in diesem Fall ist es die TextBox), z. B. "FocusableControl".
Mein Code (im Code-Behind für die FieldTextBox enthalten), um dann den Fokus auf das Steuerelement zu setzen, würde sein:
Control control = (Control)this.Template.FindName("FocusableControl", this);
if (control != null)
{
control.Focus();
}
Diese Lösung funktioniert. Aber kennt jemand eine andere Lösung, die effizienter ist als diese?