Reputation: 4240
I am trying to achieve the following:
Everything works fine until I come to closing the popup.
From searching elsewhere I am aware that I need Staysopen to be set to false ( which it is) I also read the best way is to bind the IsOpen value to a property in the view model and set its binding to 2 way ( also done )
As a side note I have found that if I add a textbox and click inside the box, when I then click outside the popup it closes as desired.
Another thing I unsuccessfully tried as a workaround was to programmatically set the keyboard focus on the text box to get the "autoclose" functionality I desired.
Here is code:
xaml -
<Popup Name="PredictionsPopup" Height="200" Width="200" AllowsTransparency="false" StaysOpen="False" IsOpen="{Binding DisplaySummaryPopup, Mode=TwoWay}">
<StackPanel Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<TextBlock Text="here is some stuff" />
<TextBox Name="hiddenBox" Text="moo"/>
</StackPanel>
</Popup>
Codebehind that sets the property on the viewmodel when the menu item is selected.
private void CurrentPredicitions_OnClick(object sender, RadRoutedEventArgs e)
{
PredictionsPopup.Placement = PlacementMode.MousePoint;
ViewModel.DisplaySummaryPopup = true;
}
Viewmodel property
public bool? DisplaySummaryPopup
{
get
{
return this.displaySummaryPopup;
}
set
{
this.displaySummaryPopup = value;
RaisePropertyChanged(() => this.DisplaySummaryPopup);
}
}
Please let me know if you need anymore details.
Upvotes: 4
Views: 4353
Reputation: 1925
Here you have a working example:
MainWindow XAML:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Popup Name="PredictionsPopup" Height="200" Width="200" AllowsTransparency="false" StaysOpen="False" IsOpen="{Binding DisplaySummaryPopup, Mode=TwoWay}">
<StackPanel Background="Red">
<TextBlock Text="here is some stuff" />
<TextBox Name="hiddenBox" Text="moo"/>
</StackPanel>
</Popup>
<DataGrid AutoGenerateColumns="False" Name="dataGrid1" IsReadOnly="True" >
<DataGrid.Columns>
<DataGridTextColumn Header="Site" Width="150" />
<DataGridTextColumn Header="Subject" Width="310" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Click Me" Click="ButtonBase_OnClick">
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
</Window>
MainWindow cs :
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
PredictionsPopup.Placement = PlacementMode.MousePoint;
PredictionsPopup.IsOpen = true;
}
ViewModel:
public class TestViewModel : INotifyPropertyChanged
{
private bool _displaySumarry;
public bool DisplaySummaryPopup
{
get { return _displaySumarry; }
set
{
_displaySumarry = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I think that your implementation for INotifyPropertyChanged is the one which causes the problem. I tried myself the code and is working now.
Upvotes: 3
Reputation: 11
I faced same problem a few times. Every time it was occuring, when a popup was changing its "isOpen" property to true from an event, which was raised from listview or datagrid element, like selectedItemChanged event, or items mouseUp event. I don't know reason, however resolved it by opening the popup from another task with code as below:
Task.Run(()=> Dispatcher.Invoke( () => myPopup.IsOpen = true));
Dispatcher is used to avoid an exception from changing any GUI object property from another than the main thread.
Upvotes: 1
Reputation: 101
For me, the solution was to add this line in the constructor of the popup's code-behind:
LostFocus += delegate { this.IsOpen = false; };
Many hours were spent, when such a quickie line was all it took :)
Upvotes: 2
Reputation: 4016
Had the same problem. The reason was, that the toggle button's ClickMode property was set to "Press". Setting it back to "Release" solved it :).
Upvotes: 2
Reputation: 4240
After trying to track this problem down I worked out that the issue is something to do with the context menu. I know this because as per the answer above instead of launching my popup via a context menu I launched it from a test button and all worked as expected.
I still don't know the exact reason for this issue but I think its something to do with the fact that the context menu is itself a subclass of popup and the focus isn't being set correctly on the new popup, so it never detects popup loss and closes.
To get round my problem I have added a close button to the popup, and then whenever the active tab in the control that hosts the popup changes it fires an event that the popup picks up and closes.
Upvotes: 2