2008-10-01 26 views
3

在我正在开发的应用程序中,我们有一大堆自定义控件,它们在Generic.xaml中定义了ControlTemplates。将注意力集中在WPF中ControlTemplate中的控件上

举例来说,我们的自定义文本框将类似于此:

<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> 

在我们的应用中,我们需要能够以编程方式将焦点设置在控件模板中的特定控制。

在我们的C#代码中,我们可以根据我们的数据找到特定的“FieldTextBox”。一旦我们有了正确的FieldTextBox,我们需要能够将焦点设置在ControlTemplate中包含的实际TextBox上。

我想出的最佳解决方案是在每个控件模板(在本例中为TextBox)的主控件上设置一个名称,例如“FocusableControl”。

我的代码(包含在代码隐藏的FieldTextBox)来然后设置侧重于控制将是:

Control control = (Control)this.Template.FindName("FocusableControl", this); 
    if (control != null) 
    { 
     control.Focus(); 
    } 

此解决方案。但是,是否有其他人知道比这更高效的解决方案?

回答

2

在您的控件模板中,您可以添加一个触发器,它将StackPanel的FocusManager的FocusedElement设置为您要关注的文本框。将触发器的属性设置为{TemplateBinding IsFocused},以便在包含的控件集中时触发。

+0

ControlTemplate的触发器不需要TemplateBinding。只需将触发器的属性设置为“IsFocused”即可。该解决方案有效,但我不确定它是否真的更有效。 – 2008-10-01 18:11:23

+1

如果您可以详细说明您的解决方案,我们可能会在这里得到一个可接受的答案。我正在尝试做类似的事情,我正在试验你的建议,但我并没有完全遵循触发器的Value绑定在其他细节中的样子。 – jpierson 2011-02-11 02:47:44

0

您可以通过提供一些DependancyProperty,并在基于DependancyProperty的controlLoaded或OnApplyTemplate函数中具有相同的代码,从而摆脱代码中控件名称的硬编码。 此DependancyProperty的发件人将为.Focus()调用的候选人。

相关问题