Minha resposta não aborda a questão acima diretamente, no entanto, eu sinto que a formulação dela fez com que ela se tornasse "A Questão" sobre como se livrar programaticamente do foco. Um cenário comum onde isso é necessário é que o usuário consiga limpar o foco clicando com o botão esquerdo do mouse no plano de fundo de um controle raiz, como uma janela.
Então, para conseguir isso, você pode criar um comportamento anexado que mudará o foco para um controle criado dinamicamente (no meu caso, um rótulo vazio). É preferível usar esse comportamento nos elementos de nível mais alto, como janelas, pois ele itera por meio de seus filhos para encontrar um painel ao qual possa adicionar um rótulo fictício.
public class LoseFocusOnLeftClick : Behavior<FrameworkElement>
{
private readonly MouseBinding _leftClick;
private readonly Label _emptyControl = new Label() { Focusable = true, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top };
public LoseFocusOnLeftClick()
{
_leftClick = new MouseBinding(new RelayCommand(LoseFocus), new MouseGesture(MouseAction.LeftClick));
}
protected override void OnAttached()
{
AssociatedObject.InputBindings.Add(_leftClick);
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
protected override void OnDetaching()
{
AssociatedObject.InputBindings.Remove(_leftClick);
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
AssociatedObject.Loaded -= AssociatedObject_Loaded;
AttachEmptyControl();
}
private void AttachEmptyControl()
{
DependencyObject currentElement = AssociatedObject;
while (!(currentElement is Panel))
{
currentElement = VisualTreeHelper.GetChild(currentElement, 0);
}
((Panel)currentElement).Children.Add(_emptyControl);
}
private void LoseFocus()
{
_emptyControl.Focus();
}
}