Daniele Sartori Daniele Sartori - 2 years ago 77
C# Question

How to prevent Popup losing focus?

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
.

mm8 mm8
Answer Source

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;
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download