Does anyone know how I can place a Popup Control in the Center of the screen?
Thanks!
Use the Placement and PlacementTarget properties to position it relative to whatever panel is at the root of the window. So if I have a Grid, StackPanel, etc. that contains all the other "stuff" in the window called MainPanel, I do something like:
<Popup
PlacementTarget="{Binding ElementName=MainPanel}"
Placement="Center"
>
First, you can use the static properties FullPrimaryScreenHeight, FullPrimaryScreenWidth of the System.Windows.SystemParameters class to get the height and width of the screen. Then, you can set the Top and Left properties of your Popup Control using the width and height before showing it.
Something like.
double primScreenHeight = System.Windows.SystemParameters.FullPrimaryScreenHeight;
double primScreenWidth = System.Windows.SystemParameters.FullPrimaryScreenWidth;
_yourControl.Top = (primScreenHeight - _yourControl.Height) / 2;
_yourControl.Left = (primScreenWidth - _yourControl.Width) / 2;
None of these answers worked for me in part because I don't have the size of the Popup. I ended up doing this in code behind as follows:
var popup = new Popup
{
Child = new YourUIControlHere(),
Placement = PlacementMode.Center,
PlacementRectangle = new Rect(new Size(
SystemParameters.FullPrimaryScreenWidth,
SystemParameters.FullPrimaryScreenHeight))
};
This could easily be extended to XAML by adding a binding for the screen size.
An obvious enhancement is to use the current screen for multi-monitor support. Getting the current window dimensions is considerably more work however.
Use Grid as container and Alignment will work fine for you:
<Popup IsOpen="True">
<Grid Name="canvasMain">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
...
</StackPanel>
</Grid>
</Popup>
You can use Placement="Center" and find ancestor Window using RelativeSource and set "PlacementTarget" property as property like this:
<Popup
Placement="Center"
PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
PopupAnimation="Slide">
<ContentControl Content="{Binding Yourcontent}"/>
</Popup>
And to keep stupid comments refrained: I know this centers the popup in the middle of the parent window (not neccessarily middle of the screen [if the parent window is not centered on the screen, what really is not regular case]) but this shall statisfy in most of the cases.
Related
I'm trying to show a fullscreen popup along with application bar. To do this I'm using such code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Name="myButton" Content="Show PopUP" Click="myButton_Click"/>
<Popup x:Name="myPopup">
<Grid Name="PopupsGrid" Background="ForestGreen">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="This is my PopUp"/>
</Grid>
</Popup>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Label="Done" Icon="Setting"/>
<CommandBar.SecondaryCommands>
<AppBarButton Label="Command"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
private void myButton_Click(object sender, RoutedEventArgs e)
{
var bounds = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().VisibleBounds;
PopupsGrid.Height = bounds.Height - 25; // to show the problem - normally we can substract BottomAppBar.Height
PopupsGrid.Width = bounds.Width;
myPopup.IsOpen = true;
}
I've figured out that we can use ApplicationView.GetForCurrentView().VisibleBounds to calculate the desired height. So far so good, but when I open the popup it overlaps the application bar (see picture 2). On the other hand once we open the appbar, it seems to be overlapped partially (see picture 3).
I've tested it both on desktop and mobile and the same problem occurs.
Am I missing something? How to put application bar above popup?
I don't think we can make sure commandbar is always above the popup. The popup command you saw in the third screenshot is actually a popup control so it can be above "myPopup" in this scenario. But, if you set the commandbar's IsSticky and IsOpen to true, when you click the button to show popup, it will hide the popup command. Popups follows this rule: latest on the top.
For the "overlapped partially" issue, instead of making the popup full screen, I think we can dynamically change the popup's height based on Commandbar's height.
One thing you may not notice is the height of LayoutRoot(Child of CommandBar) is larger than CommandBar's. By checking the default style of the CommandBar, you can find it uses Grid.Clip and RectangleGeometry.Transform to control the size of the commandbar we can see. You can also check it in the Live Visual Tree in VS. In my case, mycommandbar's Actual height is 48, and LayoutRoot's Actual Height is 60.
So as a workaround, in Compact mode, we can dynamically change the height of "myPopup" by listening the IsOpen property of the commandbar. If IsOpen = true, then substract the LayoutRoot's height(60), if IsOpen = false, substract the height of CommandBar(48).
This works for me.
Try to give your layout some padding ?
I have need to programmatically create a TextBlock inside a WrapPanel. This TextBlock will act like a heading, therefore I don't want anything to appear to right of the TextBlock. Is there a better way to max out the Width of the TextBlock without doing something like;
myTexblock.Width = 1000000;
Thanks
I think a better solution than putting your header in your WrapPanel is to place the header and WrapPanel in a StackPanel
Something similar to this:
<StackPanel>
<TextBlock Text="Some Header Text"
HorizontalAlignment="Stretch" />
<WrapPanel>
<Button Content="Placeholder" />
<Button Content="Also holding a place" />
</WrapPanel>
</StackPanel>
This gives the same visual effect as what you described without the sloppy property setting.
I am trying to create a floating control in WPF that can receive touch events. I searched a lot and the only solution for a floating control I found was the Popup control. Problem: The Popup control cannot receive touch events. And since I am using a SurfaceListBox inside my Popup, I need touch events. I tried to make the popup receive touch events via the following:
TouchExtensions.EnableSurfaceInput((HwndSource)HwndSource.FromVisual(this.selectionListPopup));
but it didn't have any effect. Is there any way to make popups receive touches? Is there any other control or way that could be used?
My end goal is to have a control that is floating above other controls - that means it is not clipped or obscured by other controls.
Here is the XAML I used so far:
<Popup Name="selectionListPopup"
PlacementTarget="{Binding ElementName=selectedItemButton}"
Placement="Relative"
VerticalOffset="{Binding ElementName=this, Path=SelectionListTop}"
HorizontalOffset="{Binding ElementName=this, Path=SelectionListLeft}"
IsOpen="{Binding ElementName=this, Path=IsSelecting, Mode=TwoWay}"
StaysOpen="False"
AllowsTransparency="True"
Focusable="False">
<s:SurfaceListBox Name="selectionList"
ItemsSource="{Binding ElementName=this, Path=ItemsSource}"
SelectedItem="{Binding ElementName=this, Path=SelectedItem, Mode=TwoWay}"
SelectionChanged="OnSelectionListSelectionChanged">
</s:SurfaceListBox>
</Popup>
It's not the HwndSource of the Popup, but the HwndSource of the visual parent of the Popup.Child. Sounds strange, I know.
So in the Opened-event of my popup I call the following code:
var myPopup = sender as Popup;
HwndSource hwndSource = (HwndSource)PresentationSource.FromVisual((Visual)VisualTreeHelper.GetParent(myPopup.Child));
hwndSource.EnableSurfaceInput();
Hi at present I am using a grid with Image and two Buttons for showing a custom message box in my WP7 application whose visibility is collapsed at first. All is working fine but I have to disable all the controls behind on the page when its visibility is visible. So its quite a overhead to enable/disable lots of control behind.
Is there a better solution for my requirement which are :(1) To show a message box having image and two button or textbox and (2) It should appear in the middle of page.
Thanks in advance!!
You can use built in Popup control with an attached behaviour written by Kent Boogaart, so it would behave like WPF Popup control with PlacementTarget and Placement:
<Popup b:PopupPlacement.PlacementTarget="{Binding ElementName=someElement}">
<b:Popup.PreferredOrientations>
<b:PopupOrientationCollection>
<b:PopupOrientation Placement="Top" HorizontalAlignment="Center"/>
<b:PopupOrientation Placement="Bottom" HorizontalAlignment="Center"/>
<b:PopupOrientation Placement="Right" VerticalAlignment="Center"/>
<b:PopupOrientation Placement="Right" VerticalAlignment="TopCenter"/>
</b:PopupOrientationCollection>
</b:Popup.PreferredOrientations>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">My popup's contents</TextBlock>
<Image Grid.Row="1" .... />
</Grid>
</Popup>
See the article Silverlight Popup with Target Placement
Download a project
What I do in this situation is to add a Grid or Border to the page that has a transparent background and IsHitTestVisible = True. You can then add your image etc to the parent control (Grid/Border).
You need to make sure the parent control covers the whole page and then just center the dialog inside this control. When you toggle the visibility of the parent control then the transparent background will overlay the other controls on the page, effectively disabling them.
Here is an example. The uxMessageGrid is the parent control and the Border is the actual dialog. You then just need to make sure this is the last control added to the root element and toggle uxMessageGrid.Visibility in your code.
<Grid x:Name="uxLayoutRoot">
<Other Controls />
<Grid x:Name="uxMessageGrid"
Visibility="Collapsed"
Background="Transparent"
IsHitTestVisible="True">
<Border CornerRadius="0"
BorderThickness="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="{StaticResource PhoneForegroundBrush}"
Background="{StaticResource PhoneBackgroundBrush}">
<TextBlock Margin="15"
Text="Message..."
TextWrapping="Wrap"/>
</Border>
</Grid>
</Grid>
Use the Custom Dialog box features of the Coding4Fun toolkit
http://coding4fun.codeplex.com/
The toolkit has many controls available beyond the standard Silverlight Toolkit and should more than meet your needs.
Try this one, may be it helps to you
StackPanel st = new StackPanel();
StackPanel st1 = new StackPanel();
Image image = new Image();
image.Height = 300;
image.Width = 300;
image.Source = new BitmapImage(new Uri("/PhoneApp1;component/Koala.jpg", UriKind.Relative));//Build Action=Resource
Button btnok = new Button();
btnok.Content = "Ok";
btnok.Click += new RoutedEventHandler(btnok_Click);
Button btncancel = new Button();
btncancel.Content = "Cancel";
btncancel.Click += new RoutedEventHandler(btncancel_Click);
st1.Orientation = System.Windows.Controls.Orientation.Horizontal;
st1.Children.Add(btnok);
st1.Children.Add(btncancel);
st.Children.Add(image);
st.Children.Add(st1);
ContentPanel.Children.Add(st);
How do I change the size of the AuxilaryPane in the WPF Ribbon ApplicationMenu? I have added a recent file list to that area but it is getting truncated. Ideally I'd like the auxilary pane to fill the screen like it does for Word/Excel.
My code:
<r:Ribbon.ApplicationMenu>
<r:RibbonApplicationMenu>
<r:RibbonApplicationMenu.AuxiliaryPaneContent>
<StackPanel>
<TextBlock Text="Recent Files" />
<Separator />
<ItemsControl ItemsSource="{Binding RecentFiles}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<r:RibbonApplicationMenuItem Header="{Binding ShortPath}"
Command="{Binding DataContext.OpenRecentFileCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding LongPath}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</r:RibbonApplicationMenu.AuxiliaryPaneContent>
</r:RibbonApplicationMenu>
</r:Ribbon.ApplicationMenu>
Based on the answers in this thread I found it easiest to subclass RibbonApplicationMenu and set Width of the third column to Auto.
public class CustomRibbonApplicationMenu : System.Windows.Controls.Ribbon.RibbonApplicationMenu
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
System.Windows.DependencyObject obj = this.GetTemplateChild("PART_AuxiliaryPaneContentPresenter");
System.Windows.Controls.ContentPresenter c = obj as System.Windows.Controls.ContentPresenter;
((System.Windows.Controls.Grid)((System.Windows.Controls.Border)c.Parent).Parent).ColumnDefinitions[2].Width = System.Windows.GridLength.Auto;
}
}
Now you just need to change your Ribbon xaml from
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu>
to
<Ribbon.ApplicationMenu>
<ctrl:CustomRibbonApplicationMenu>
If you are looking for a very quick fix to increase the height, you can simply add some useless RibbonApplicationMenuItems to pad out the box (and not have to modify MS source code).
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu>
<ribbon:RibbonApplicationMenu.Items>
<ribbon:RibbonApplicationMenuItem Name="saveSettings" Header="Save Settings" />
<ribbon:RibbonApplicationMenuItem IsEnabled="False"/> <!--USELESS-->
<ribbon:RibbonApplicationMenuItem IsEnabled="False"/> <!--USELESS-->
</ribbon:RibbonApplicationMenu.Items>
<ribbon:RibbonApplicationMenu.AuxiliaryPaneContent >
<StackPanel Orientation="Vertical" >
<GroupBox>
<Label Content="System Settings" />
</GroupBox>
<StackPanel Orientation="Horizontal">
</StackPanel>
</StackPanel>
</ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
I've searched a solution for the same problem.
There is no direct property to modify this.
An Example of creating such property can be found at
msdn
here's the main solution:
Change the source code of the Ribbon Library. MS has provided the source code of the Ribbon Library: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2bfc3187-74aa-4154-a670-76ef8bc2a0b4
Download the source code and open it, in the MicrosoftRibbonForWPFSourceAndSamples\RibbonControlsLibrary\Microsoft\Windows\Controls\Ribbon\RibbonApplicationMenu.cs, add one Dependency Property:
public double MinMenuHeight
{
get { return (double)GetValue(MinMenuHeightProperty); }
set { SetValue(MinMenuHeightProperty, value); }
}
public static readonly DependencyProperty MinMenuHeightProperty =
DependencyProperty.Register("MinMenuHeight", typeof(double), typeof(RibbonApplicationMenu), new UIPropertyMetadata(0.0));
In the MicrosoftRibbonForWPFSourceAndSamples\RibbonControlsLibrary\Themes\Generic.xaml, line 7519, add the XAML code:
<Border x:Name="PopupBorder" MinHeight="{TemplateBinding MinMenuHeight}" BorderBrush="{Binding RelativeSource={RelativeSource AncestorType={x:Type ribbon:RibbonMenuButton}}, Path=Ribbon.BorderBrush}" Background="{Binding RelativeSource={RelativeSource AncestorType={x:Type ribbon:RibbonMenuButton}}, Path=Ribbon.Background}" BorderThickness="1" CornerRadius="2">
<Grid>
</Grid>
</Border>
Only add the first two rows of the given xaml
This is an old thread, yes, and it has some good ideas, but I wasn't satisfied.
My problem was slightly different in that I needed the ApplicationMenu to expand only enough to fit any control that was placed in the auxiliary pane.
Eventually I dug deep and found a solution I was happy with. It doesn't solve the "fill the screen" problem, but I'm hoping this will help others who land here, looking for a solution to a problem similar to mine. Sorry if it looks like I'm trying to hijack the thread. I don't intend to.
Essentially I solved the fixed width and height problem by changing the ribbon style:
Open the ribbon assembly in JetBrains DotPeek
Open Resources/System.Windows.Controls.Ribbon.g.resources/Themes/generic.baml
Copy the entire resource dictionary into a .xaml file in your project. You may be able to get away with using only a part of it, but I decided to take the whole thing.
At this point you may be asking, "Why not just use VS or Blend or ShowMeTheTemplate instead of DotPeek?" All of these tools failed miserably on the ribbon assembly. Don't know why. They didn't say. One of the problems with using DotPeek is that some of the namespace references will need adjusting, but it's not too difficult, so I won't go into details here.
So, now that you have all the styles and templates, go look for the offending markup.
First, fix the width:
Look for the grid whose third column definition is a static value of 300. You can search for <ColumnDefinition Width="300"/>. There is only one.
Change the "300" to "Auto".
Then fix the height:
Look for the definition of PART_SubmenuPlaceholder Border. You can search for x:Name="PART_SubmenuPlaceholder". It is about 50 lines below the change you did for the width.
That Border binds the Height property to the ActualHeight property of the "MainPaneBorder" control: Height="{Binding ElementName=MainPaneBorder, Path=ActualHeight}".
Remove this Height definition.
Now that you've modified the style, just add this resource dictionary to your xaml and it should apply itself to the ribbon.
When I came across this answer (while searching for an answer to my own, slightly different question), I wasn't too excited about actually modifying Microsoft code.
As a result, I rather preferred to subclass it, and get the hold of the necessary UI element using base.GetTemplateChild on the relevant "PART_...".
I suppose you can follow a similar approach to achieve what you need.
My example is here.
Hope this helps.
P.S. If you happen to find a way to determine the necessary width of the AuxiliaryPanel, please let me know - I would like to see if that's applicable to the menu's width as well.
You can download the Microsoft Ribbon for WPF Source Code (http://www.microsoft.com/en-us/download/details.aspx?id=11877) and add a DependencyProperty Width/Height to ApplicationMenu or just do it 'quick and dirty' like in my example:
MainWindow.xaml
public partial class MainWindow : RibbonWindow
{
private Size DefaultApplicationMenuSize;
public MainWindow()
{
InitializeComponent();
}
private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
{
var grid = (myRibbon.ApplicationMenu.Template.FindName("MainPaneBorder", myRibbon.ApplicationMenu) as Border).Parent as Grid;
/* before the first opening of the menu the size is NaN, so you have to measure size and use the DesiredSize */
grid.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
this.DefaultApplicationMenuSize = new Size(grid.ColumnDefinitions[2].Width.Value, grid.DesiredSize.Height);
}
private void RibbonApplicationMenuItem_MouseEnter(object sender, MouseEventArgs e)
{
Button b=new Button();
b.Content = "my epic button";
b.Width = 500;
b.Height = 500;
b.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
SetApplicationMenuSize(b.DesiredSize);
this.ribbonContentPresenter.Content = b;
}
private void RibbonApplicationMenuItem_MouseLeave(object sender, MouseEventArgs e)
{
SetApplicationMenuSize(DefaultApplicationMenuSize);
this.ribbonContentPresenter.Content = null;
}
private void SetApplicationMenuSize(Size size)
{
var grid = (myRibbon.ApplicationMenu.Template.FindName("MainPaneBorder", myRibbon.ApplicationMenu) as Border).Parent as Grid;
/* you can modify the width of the whole menu */
//grid.Width = size.Width;
/* or just the size of RibbonApplicationMenu.AuxiliaryPaneContent */
grid.ColumnDefinitions[2].Width = new GridLength(size.Width);
grid.Height = size.Height;
}
}
MainWindow.xaml.cs
<ribbon:RibbonWindow x:Class="WpfRibbonApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
Title="MainWindow"
x:Name="RibbonWindow"
Width="640" Height="480"
Loaded="RibbonWindow_Loaded">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ribbon:Ribbon x:Name="myRibbon">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png">
<ribbon:RibbonApplicationMenuItem Header="Hello _Ribbon"
ImageSource="Images\LargeIcon.png"/>
<ribbon:RibbonApplicationMenuItem Header="HoverTest"
ImageSource="Images\LargeIcon.png"
MouseEnter="RibbonApplicationMenuItem_MouseEnter"
MouseLeave="RibbonApplicationMenuItem_MouseLeave"
StaysOpenOnClick="True" />
<ribbon:RibbonApplicationMenu.FooterPaneContent>
<ribbon:RibbonButton Label="What ever" HorizontalAlignment="Right"/>
</ribbon:RibbonApplicationMenu.FooterPaneContent>
<ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
<ribbon:RibbonContentPresenter Name="ribbonContentPresenter" />
</ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
</ribbon:Ribbon>
</Grid>
</ribbon:RibbonWindow>
have a nice day