0
votes

I have a DataTemplate which contains a TextBox. The DataTemplate is bound to the ContentTemplate property of a Style for the DevExpress FlyoutControl. The Flyout Control itself is within the ControlTemplate of another TextBox.

When the TextBox with the FlyoutControl is focused, I want to redirect focus to the first TextBox in the FlyoutControl's ContentTemplate (from the DataTemplate). Setting FocusManager.FocusedElement={Binding RelativeSource={RelativeSource Self}} on the TextBox I want focused accomplishes this the first time, but once the Flyout has loaded it no longer works.

I have tried every suggestion I can find and nothing so far has worked. I can get the TextBox I want to reference in code and call Focus(), but it always returns false. At best, when I try to focus it in code, the Flyout is focused instead, but never the TextBox within the Flyout.

Here is what each relevant part looks like (irrelevant code omitted):

<DataTemplate x:Key="FlyoutTemplate">
   <Grid>
      <dxe:TextEdit x:Name="TextThatWantsFocus"
        FocusManager.FocusedElement={Binding RelativeSource={RelativeSource Self}}" />
   </Grid>
</DataTemplate>

...

<Style x:Key="FlyoutStyle" TargetType="dxe:FlyoutControl">
   <Setter Property="ContentTemplate" Value="{StaticResource FlyoutTemplate}"/>
</Style>

...

<dxe:TextEdit>
   <dxe:TextEdit.Template>
      <ControlTemplate>
         <StackPanel>
            <dxe:TextEdit x:Name="InnerTextEdit" />
            <dxe:FlyoutControl Style="{StaticResource FlyoutStyle}"/>
         </StackPanel>
      </ControlTemplate>
   </dxe:TextEdit.Template>
</dxe:TextEdit>

The flyout is being opened in code. It is here that I also would like to focus the TextBox (TextThatWantsFocus). However, nothing I have tried will give it focus (except for FocusManager handling it the first time), including the typical SO answer involving triggers. Any ideas would be greatly appreciated.

2
Try using a Behavior. You can create a custom behavior that will focus a specific control on some event and then attach that behavior to the appropriate control (i.e. your text box) so that whenever its made visible or whatever event you're interested in, it grabs focus. - Todd Bowles

2 Answers

2
votes

I took DmitryG's advice and submitted a DevExpress support ticket, and they were able to provide a solution.

The issue was resolved by handling the Loaded event of the TextEdit I want focused and using the dispatcher to focus it:

private void TextThatWantsFocus_Loaded(object obj, RoutedEventArgs e)
{
    var text = obj as FrameworkElement;
    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate()
        { text.Focus(); }));
}
1
votes

I suggest you using the FocusBehavior from DevExpress MVVM Framework:

<DataTemplate x:Key="FlyoutTemplate">
   <Grid>
      <dxe:TextEdit>
        <dxmvvm:Interaction.Behaviors>
            <local:FocusBehavior/>
        </dxmvvm:Interaction.Behaviors>
      </dxe:TextEdit>
   </Grid>
</DataTemplate>