In a Usercontrol Grid(Grid1) I have a textBox, two Buttons (Search and Save Buttons) and Two Popups(Popup1 and Popup2). Inside Popup2 there is a textBox and one button(Search). I wanted to hide the popups(both 1 and 2) when when the user click outside the Grid1. Rightnow I can hide the Popups but NOT able to click the button inside Popup2. As soon as I Click the SearchButton inside the Popup2 it hides Popups.
I have set the StaysOpen Property for both Popups to a bool prop like this: StaysOpen="{Binding PopupStaysOpen}"
Thanks.
-Menon
private void Grid1_LostFocus(object sender, RoutedEventArgs e)
{
(this.DataContext as ViewModel).PopupStaysOpen = false;
}
Related
I have a MetroWindow. It has a Flyout. The Flyout has a button. When the Flyout button is pressed, a new MetroWindow is shown and the flyout is dismissed.
What occurs is:
User pressed button on Flyout.
The button-press opens a new non-modal form and sets the Flyout's IsOpen to false.
The non-modal form opens on top of everything.
The flyout closes.
The main form gets the focus after the flyout closes - hiding the non-modal form.
I would like the focus-change to the main form to not occur when the flyout closes.
I have a method that works, but it's a bit laggy because it has to wait for the flyout animation to finish.
Is there a better way? I do not want to make the new window to be modal or AlwaysOnTop.
private void SearchResultClose(object sender, RoutedEventArgs e)
{
m_EvtResultClosed.Set();
}
private void SearchResultOpenChange(object sender, RoutedEventArgs e)
{
if (foSearchResult.IsOpen)
{
m_EvtResultClosed.Reset();
}
}
and
<controls:Flyout Position="Top" Header="" x:Name="foSearchResult"
Height="275" ClosingFinished="SearchResultClose" IsOpenChanged="SearchResultOpenChange">
and
private void OpenPersonCard(object sender, RoutedEventArgs e)
{
var selected_person = SearchPersonResultsVM.View.CurrentItem as Editable<Person>;
if (selected_person != null)
{
var card = new PersonFileWindow();
card.Person = selected_person;
foSearchResult.IsOpen = false;
// Wait for it to close, and then show the form.
Dispatcher.BeginInvoke(new Action(async () =>
{
await Task.Run(() =>
{
m_EvtResultClosed.WaitOne();
});
card.Show();
}), null);
}
}
where
private AutoResetEvent m_EvtResultClosed = new AutoResetEvent(false);
See the function IsOpenedChanged in MahApps' Flyout.cs and we see it calls Focus() on close whether its animated or not. It is also comment :
// focus the Flyout itself to avoid nasty FocusVisual painting (it's visible until the Flyout is closed)
But I do not know what it is trying to resolve exactly.
https://github.com/MahApps/MahApps.Metro/blob/1.2.4/MahApps.Metro/Controls/Flyout.cs
The simplest hack is adding Focusable="False" to your flyout as:
<controls:Flyout Focusable="False" Position="Top" Header="" x:Name="foSearchResult"Height="275" ClosingFinished="SearchResultClose" IsOpenChanged="SearchResultOpenChange">
It works fine here and I can't tell any nasty FocusVisual painting as commented in the source.
By default, when opened, the Flyout steals focus for itself, or if Focusable==false, for some control within it, even the close button. In any case, focus is not restored to the previous element.
So, just setting Focusable="False" probably won't solve the problem.
Instead, Flyout provides the AllowFocusElement property to suppress this behavior:
<controls:Flyout AllowFocusElement="False" ... >
I created a UserControl like Popup which is displayed when user clicks on menu item.
If user clicks side that user control should be collapsed.
It works fine for me when user clicks side other than any control.
If I click on datagrid or listbox it is not hiding.
Here is my code:
<src:AddNewItemPopUp x:Name="PopUp" Margin="111,47,620,230" Panel.ZIndex="1" Visibility="Collapsed"/>
I took a button in click event I set PopUp visibility property to true
In my user control I have grid. In the mousedown event of grid I have written following code...
private void Grid_MouseDown_1(object sender, MouseButtonEventArgs e)
{
if (PopUp.Visibility == Visibility.Visible)
{
PopUp.Visibility = Visibility.Collapsed;
}
}
If I click on any control like a Button, DataGrid, ListBox that are placed in Grid Popup is not collapsed.
First Set Grid's Background Property, for example grid.Backgroung=Brushes.Transparent or in Xaml Backgroung = "Transparent"
Second Handle PreviewMouseDown event instead of MouseDown event.
The first one makes the mouse event to fire, when mouse is directly over the grid.
The second one makes the mouse event fire, when mouse is over an UIElement in the grid.
Try:
Visibility="Hidden"
that is:
private void Grid_MouseDown_1(object sender, MouseButtonEventArgs e)
{
if (PopUp.Visibility == Visibility.Visible)
{
PopUp.Visibility = Visibility.Hidden;
}
}
and also see:
http://msdn.microsoft.com/en-us/library/system.windows.visibility.aspx
If the user clicks on the overlay, I want the ChildWindow to automatically close and return the user to the main screen.
Is there a property that controls this? If not, is there a way to attach a click handler to the overlay?
Turns out you can get a reference to the overlay right after it is created. After that it is a simple matter of attaching the event handler.
private void Overlay_MouseButtonDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var overlay = (Grid)GetTemplateChild("Overlay");
overlay.MouseLeftButtonDown += Overlay_MouseButtonDown;
overlay.MouseRightButtonDown += Overlay_MouseButtonDown;
}
On a grid, i have a ListBox and a button. If the button is clicked, an item is added to the listbox.
The problem i'm trying to fix is that after the item is added, it is not focused.
I want to automatically scroll down the listbox so that an user can see the item that is lately added. Any thought?
You can set the SelectedIndex property to set the currently selected item.
If it scrolls of the page, you can use ScrollIntoView() to keep the bottom of the list showing.
listBox1.SelectedIndex = listBox1.Items.Count;
listBox1.ScrollIntoView(listBox1.SelectedItem);
I had to force the call to ScrollIntoView onto the UI thread and this seemed to do the trick.
Here's an example of this working. A
dd this as the event handler of an application bar icon button click event in a new DataBound application.
private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
App.ViewModel.Items.Add(new ItemViewModel
{
LineOne = "new L1",
LineTwo = "new L2",
LineThree = "new L3"
});
Dispatcher.BeginInvoke(() =>
MainListBox.ScrollIntoView(MainListBox.Items.Last()));
}
I try to use link button click event to create a popup with some data list.but the default position of popup is top-left of the whole browser window.
It seems different control need different way to position popup. like Image control with LeftButtondown/up event would be different from click event for button/link button.
How to set the popup position right under the link button?
There are two approaches.
Option 1
You can position a popup via its HorizontalOffset and VerticalOffset properties. You just need to workout what values to set them to. Like this:-
private void Button_Click(object sender, RoutedEventArgs e)
{
Popup popup = new Popup();
Button b = (Button)sender;
GeneralTransform gt = b.TransformToVisual(Application.Current.RootVisual);
Point p = gt.Transform(new Point(0, b.ActualHeight));
popup.HorizontalOffset = p.X;
popup.VerticalOffset = p.Y;
popup.Child = new Border()
{
Child = new TextBlock() { Text = "Hello, World!" },
Background = new SolidColorBrush(Colors.Cyan)
};
}
Here we use the TrannsformToVisual method of the button to get a transform relative to the application root visual which has the same origin that the popup will have. Using the buttons actual height we can arrive at a point at the bottom left corner of the button.
Option 2
An alternative is place the Popup in the layout.
<StackPanel>
<Button Content="Click Me" Click="Button_Click" />
<Popup x:Name="popup" />
<TextBlock Text="This text will be occluded when the popup is open" />
</StackPanel>
code:-
private void Button_Click(object sender, RoutedEventArgs e)
{
popup.Child = new Border()
{
Child = new TextBlock() { Text = "Hello, World!" },
Background = new SolidColorBrush(Colors.Cyan)
};
popup.IsOpen = !popup.IsOpen;
}
In this approach the origin of the Popup is placed by the layout system, in this case we have used a StackPanel so the popup is placed directly below the button. However the popup doesn't take up any space in the layout so the textblock appears immediately below the button.