Below is a very crude start to a thumb template that eventually might look like a respectable popup window. Obviously the user can drag it around from any location therein. Is there any way to make it so it can only be dragged from the top AliceBlue border? Put another way, it is possible to disable dragging from the second border?
<Popup x:Name="MyPopup">
<Popup.Child>
<Thumb DragDelta="Thumb_DragDelta">
<Thumb.Template>
<ControlTemplate>
<StackPanel Margin="20">
<Border Height="20" Width="200" BorderBrush="Black" BorderThickness="2,2,2,0" CornerRadius="3,3,0,0" Background="AliceBlue"></Border>
<Border Height="200" Width="200" BorderBrush="Black" BorderThickness="2,0,2,2" Background="Bisque"></Border>
</StackPanel>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Popup.Child>
</Popup>
I haven't tested this so it's a bit of a guess. Add an event handler to the MouseLeftButtonDown event on AliceBlue Border. In the event handler:-
e.Handled = true;
Related
I want to instantiate two Controls (an Expander and a Button) from two ControlTemplates. They are docked in a Dockpanel (right and left). The Expander is visible and it works fine, but the Button isn't visible.
The ControlTemplate of the Button in App.xaml:
...
<ControlTemplate x:Key="OpenFileButton" TargetType="{x:Type Button}">
<Image Name="OpenFileButton" Source="F:\AudioNodeGUI_XAML\images\filebutton.jpg">
</Image>
</ControlTemplate>
...
And the instantiation in a usercontrol:
<Grid>
<Image Source="F:\AudioNodeGUI_XAML\images\FileInputNode.jpg"/>
<DockPanel Name="dock" Width="151" Height="20" Margin="27,53,122,139">
<Expander Name="expander" Template="{StaticResource FileExpander}" Height="20" Width="41" PreviewMouseLeftButtonUp="expand" DockPanel.Dock="Left">
<ListView Name="usedFiles" Background="Black" BorderBrush="Transparent" BorderThickness="0" Width="140" Height="120" Opacity="0.5">
</ListView>
</Expander>
<Button Name="OpenFileButton" Template="{StaticResource OpenFileButton}" DockPanel.Dock="Right" />
</DockPanel>
</Grid>
But the Button isn't visible, neither in the Designer (just the outline) nor in execution. What am I doing wrong?
I suspect that your issue is just incorrect path to the image file. Unfortunately you won't have any tip about this kind of error neither in designer nor in output window. However if you have ReSharper it should highlight the path to the file if it doesn't exist
I am experiencing a strange WPF popup placement issue.
I have defined this XAML:
<Window x:Class="PositionBug.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="525">
<Grid>
<TextBlock Name="Textblock1" Height="60" Width="300" Background="LightGray" HorizontalAlignment="Center"
VerticalAlignment="Bottom">The PlacementTarget</TextBlock>
<Popup Name="Popup1" PlacementTarget="{Binding ElementName=Textblock1}" Placement="Top" Width="120" Margin="198,0,199,0" IsOpen="True">
<TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
</Popup>
</Grid>
On most computers this is the result, as expected:
However, on multiple units of one specific computer model, the result is presented like this:
Is there any way to force Placement to both Top AND Left?
The left and right alignment of menus and popups appears to be controlled by this special registry key:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows
REG_SZ: MenuDropAlignment
Value: 0 means to the right
Value: 1 means to the left
Somehow my system switched the menu and popup alignment from right to left. I checked this registry key and sure enough the value was 1 so I changed it back to 0 and now my WPF Popup alignments are working as expected.
UPDATE: Here is a better solution if you want to make it apply to the entire Window: WPF Handedness with Popups
ORIGINAL:
I realize this is an old thread but I just ran across this. With this:
<Popup
Name="Popup"
Placement="Bottom"
PlacementTarget="{Binding ElementName=ToggleButton}"
...
I get this:
I didnt want to rely on the user settings and I wanted to avoid code behind and math. So I just did this DIRTY hack but using a hollow rectangle in the corner. Good thing is all of the built-in logic for shifting the popup when at different edges of the screen all still work:
<!--POPUP PLACEMENT HACK-->
<Rectangle
x:Name="PART_PopPlacer"
Fill="Red"
Width="0"
Height="0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Focusable="False"
Visibility="Hidden"
IsHitTestVisible="False"
/>
<Popup
Name="Popup"
Placement="Left"
PlacementTarget="{Binding ElementName=PART_PopPlacer}"
...
Which gave this:
The full code (should probably put the rectangle at the top of the xaml so it can be covered by the cascading elements):
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<!-- COMBO BOX STYLE AND TEMPLATE -->
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Background="White"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
/>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
Margin="2"
/>
<!--POPUP PLACEMENT HACK-->
<Rectangle
x:Name="PART_PopPlacer"
Fill="Red"
Width="0"
Height="0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Focusable="False"
Visibility="Hidden"
IsHitTestVisible="False"
/>
<Popup
Name="Popup"
Placement="Left"
PlacementTarget="{Binding ElementName=PART_PopPlacer}"
VerticalOffset="6"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True">
<Border
Name="DropDownBorder"
Background="LightYellow"
BorderThickness="1"
BorderBrush="Black"/>
<ScrollViewer Margin="2" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel>
<ComboBox Height="20" Width="50" SelectedIndex="0" Margin="20">
<ComboBoxItem Content="Very Very Very Very Long Text" />
<ComboBoxItem Content="Text" />
<ComboBoxItem Content="Text" />
<ComboBoxItem Content="Text" />
<ComboBoxItem Content="Text" />
</ComboBox>
</StackPanel>
</Page>
I was able to fix this on my HP laptop. Turns out since it has a touch screen, it uses a left/right "handedness" to choose whether drop-down menus and popups are left- or right-aligned with the target control (when using Top or Bottom alignment).
To fix, go to Control Panel, search (upper right corner) and type Tablet PC Settings. On that dialog (under General tab on some versions of Windows, and the Other tab on other PCs) you'll see options for right- and left-handed operation.
The right-justified popups are "better" if the menus and popups show to the left of the point being touched, so the right hand doesn't obscure the component. Of course if you primarily use a mouse, then it just looks weird and confuses us developers!
I had the same issue with popups in an application I'm working on. I can't expect customers to change the settings on their Tablet PCs, so I used this code to fix the popup positioning for everyone:
var simplePlacement = new CustomPopupPlacement(new Point(0, 0), PopupPrimaryAxis.None);
popup.Placement = PlacementMode.Custom;
popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback((popupSize, targetSize, offset) => new [] { simplePlacement });
Go to "system settings"
- "hardware & sound"
- "tablet pc-settings"
- "to be used writing hand"
- select "right-handed" (PopUps, DropDowns align left)
or "left-handed" (PopUps, DropDowns align right)
I have a popup defined as follows,
<Popup x:Name="popLines"
Placement="Bottom"
IsOpen="False"
Width="145" Height="42"
StaysOpen="False"
PopupAnimation="Fade"
AllowsTransparency="True"
HorizontalOffset="-2" VerticalOffset="0">
<Grid Margin="2">
<Path StrokeThickness="0.7" StrokeLineJoin="Round" Fill="#FFFFFFFF" Stretch="Fill" Stroke="Black" Data="M6.5,0.5 L30.167,0.5 30.167,8.4999992 190.16701,8.4999992 190.16701,44.166001 0.5,44.166001 0.5,8.4999992 6.5,8.4999992 6.5,0.5 z">
</Path>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBox BorderBrush="Black" BorderThickness="0.5" Margin="5,10,2,2" Width="110" Height="20" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ToolTip="Excel File Path"></TextBox>
<Image Source="/App_Desktop;component/Resources/save.png" Margin="2,10,5,2" Width="16" Height="16"></Image>
</StackPanel>
</Grid>
</Grid>
</Popup>
I set IsOpen=true when an image MouseLeftButtonDown event fires.Except, the popup disappears as soon as it appears. What is going wrong?
I think what happens is, that the the MouseLeftButtonUp event fires while the Mouse is not over the Popup. Try holding the mousebutton down and move your mouse so it is above the popup to see if it stays open, and then release the mousebutton.
you can solve this by setting StaysOpen="True" or by setting IsOpen=true in a click eventhandler or MouseButtonUp eventhandler.
Also using your example with the image, you could have a transparent area right above the image in your popup visualtree that 'captures' the MouseUp event when the popup is open. you would have to change the placement option and bind that area to the image's width and height properties.
It seems that the WPF Rectangle shape does not have the Click event defined. What am I supposed to use instead?
It does have MouseUp, but it's not quite the same behavior.
If you're not happy with MouseDown and MouseUp, perhaps you could just put the Rectangle in a Button and handle the Button's Click event?
<Button>
<Button.Template>
<ControlTemplate>
<Rectangle .../>
</ControlTemplate>
</Button.Template>
</Button>
It really depends with the behavior you're after. Please elaborate if needs be.
To add click handing to a Rectangle itself, you can use the InputBindings property:
<Rectangle Fill="Blue" Stroke="Black">
<Rectangle.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding FooCommand}"/>
</Rectangle.InputBindings>
</Rectangle>
This will cause the FooCommand to be executed when the rectangle is clicked. Handy if you're using MVVM!
I was looking for the related DoubleClick event and came across this suggestion to simply embed the object of interest in a ContentControl.
Here is their example (with a border, which also did not support click/double click).
<ContentControl MouseDoubleClick="OnDoubleClick">
<Border Margin="10" BorderBrush="Black" BorderThickness="2">
<Grid Margin="4">
<Rectangle Fill="Red" />
<TextBlock Text="Hello" FontSize="15" />
</Grid>
</Border>
</ContentControl>
Rectangle has event Tapped, which works fine. In designing universal apps for Windows 8.1, there are new events. Tapped, DoubleTaped, RightTapped and Holding.
I have a ListBox displaying some items, and in certain modes I "stamp" a kind of watermark across the top of it. I've done this with a Border containing a TextBlock with an Opacity of 0.5. All this works nicely.
However, I still want the user to be able to click on the items in the ListBox but if I click on the "stamp" it obviously eats the click events and they're not seen by the ListBox.
What do I have to do to prevent this? (i.e. allow the ListBox to see the Click event)
Thanks,
Craig
You can do this with the IsHitTestVisible property:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ListBox>
<ListBoxItem>a</ListBoxItem>
<ListBoxItem>b</ListBoxItem>
<ListBoxItem>c</ListBoxItem>
</ListBox>
<Border Opacity="0.2" Background="Cyan" BorderBrush="Black" BorderThickness="5" IsHitTestVisible="False" >
<TextBlock Text="EXAMPLE" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>