How to prevent Popup losing focus?

904 Views Asked by At

I have a Combobox defined in a data template of an ItemsControl. This ComboBox has a Button defined in it. On the Button_Click event, a Popup should be shown. This Popup contain a custom UserControl that has some controls defined inside it.

Here is the code before I explain my problem:

<ComboBox x:Name="cb" HorizontalAlignment="Center" Grid.Column="2" Width="140" Visibility="{Binding HasCombobox, Converter={StaticResource BoolToVis}}">
    <ComboBox.ItemsSource>
       <CompositeCollection>
           <CollectionContainer Collection="{Binding Source={StaticResource cvs}}" />
           <ComboBoxItem>
              <Button Click="Button_Click" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Content="{x:Static prop:Resources.INSERT_BTN}"/>
           </ComboBoxItem>
       </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>

This is the Button_Click event:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button s = sender as Button;
    var popup = new System.Windows.Controls.Primitives.Popup();
    popup.AllowsTransparency = true;
    popup.Child = new myCustomView();
    popup.PlacementTarget = s;
    popup.Placement = System.Windows.Controls.Primitives.PlacementMode.Top;
    popup.IsOpen = true;
    popup.StaysOpen = true;
}

The problem is that when I click any of the controls defined inside myCustomView the Popup loses the focus and closes. How can I force it to stay opened?

EDIT 1 :

Since myCustomView has its own ViewModel I tried to hack the Popup to stay open by binding its IsOpen property to a boolean inside the view model like this:

popup.DataContext = myCustomViewModel;
Binding b = new Binding();
b.Source = myCustomViewModel;
b.Path = new PropertyPath("stayOpened");
b.Mode = BindingMode.TwoWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.Default;
BindingOperations.SetBinding(popup, Popup.IsOpenProperty, b);
// BindingOperations.SetBinding(popup, Popup.StaysOpenProperty, b);  tried both IsOpened and StaysOpen

But the focus switch still kills my Popup.

2

There are 2 best solutions below

1
mm8 On BEST ANSWER

You could set the PlacementTarget to the parent ItemsControl and then set the VerticalOffset and HorizontalOffset properties of the Popup to specify its exact location on the screen, e.g.:

private void btn_Click(object sender, RoutedEventArgs e)
{
    Button s = sender as Button;
    System.Windows.Controls.Primitives.Popup popup = new System.Windows.Controls.Primitives.Popup();
    popup.AllowsTransparency = true;
    popup.Child = new myCustomView();
    //some stuff needed to recognise which button was pressed
    popup.PlacementTarget = ic; //<-- "ic" is the name of the parent ItemsControl
    Point p = s.TranslatePoint(new Point(0, 0), ic);
    popup.VerticalOffset = p.Y; //adjust this value to fit your requirements
    popup.HorizontalOffset = p.X; //adjust this value to fit your requirements
    popup.IsOpen = true;
    popup.StaysOpen = true;
}
1
Gareth On

You could set Popup.StaysOpen to true like this

<Popup StaysOpen="True"/>