wpf popup wrong placement wrong size - wpf

The Popup I am trying to create is in the wrong size and t doesn't seem to care about the placement I've set at all.
<Popup Name="mypopup" Width="700" Height="600" IsEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Top" >
<Grid Background="#FFFFFFF1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.606*"></ColumnDefinition>
<ColumnDefinition Width="0.394*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
</Grid>
</Popup>

Popup usually does not add as a visual child. Instead it appears in air without any connection with visual. So I suggest you to use HorizontalOffset and VerticalOffset attributes to position the popup. Also there is PlacementMode option to position the popup.
Anatomy of Popup
Regarding the popup size, I suggest to set size to the immediate child (Grid in your case) inside popup instead of setting height and width to popup.

Related

How can I detect the Mouse Wheel for the WPF WebView control?

I am trying to detect when the Mouse Wheel is being used on a WPF WebView control using the PreviousMouseWheel event. In the xaml I tried adding the tag to the WebView, but the event only fires when the mouse is somewhere outside of the WebView control. I also tried the tag on the containing Grid and the Window itself, but with the same result.
xaml:
<Grid Name="windowGrid">
<StackPanel>
<Grid x:Name="gridTest" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Controls:WebView Name="wvc" Grid.Row="0" Grid.Column="0"
Width="800" Height="600"
Source="http://www.google.ca"
PreviewMouseWheel="my_PreviewMouseWheel"
/>
</Grid>
</StackPanel>
</Grid>
Not supported. Generally bubbling routed events are used to trace state changes from UI elements. But if look at the sources on the GitHub can be found only raising for one routed event - new RoutedEventArgs(GotFocusEvent).

WPF button position dependent on another element

I would like to place my button always on the middle of the bottom frame of ScrollViewer. I am going to change both the size of window, and a size of ScrollViewer, but I want my button to be always as on the pictures.
Owing to the fact that i am following MVVM, I have just xaml. Basically, I would like to bind (live) the button top position from the pattern:
button.top = (scrollViewer.top + scrollViewer.height) - button.height/2
I would be grateful for your suggestions.
[EDIT] I forgot to add that all other controls are in grid rows and columns.
You can try to use Grid to achieve that. If you need to change the ScrollViewer size, just change ScrollGrid Grid size instead. To overlap bottom or top content, you can use negative margins for the button.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Border Background="Red"/>
<Border Background="Red" Grid.Row="2"/>
<Grid x:Name="ScrollGrid" Grid.Row="1">
<ScrollViewer></ScrollViewer>
<Button Width="100" Height="100" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
</Grid>
</Grid>

WPF XAML ListView with ScrollBars

I have a ListView which is showing both scroll bars. To achieve that, I places my ListView within a Border located in a Grid like below:
<Window ...
MinWidth="600" MinHeight="500" Width="800" Height="500"
Topmost="True"
WindowStartupLocation="CenterScreen"
SizeToContent="Height" WindowStyle="None">
<Window.Resources>
<ResourceDictionary>
...
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" MinHeight="60"/>
<RowDefinition Height="48"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="370"/> <-- THIS IS HARDCODED TO 370 BUT I NEED IT TO BE RESIZABLE
</Grid.RowDefinitions>
<Grid Margin="5,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="346*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding MyName}" Grid.Column="1"
Style="{StaticResource MyNameStyle}" Margin="0,5,0,5" />
</Grid>
<Border BorderBrush="{StaticResource MyBrush}" Grid.Row="1" Grid.Column="0" >
<ListView
x:Name="lstMyListView"
Margin="0,0,0,0"
BorderBrush="Transparent"
ItemsSource="{Binding MyItems}"
SelectedIndex="0"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto">
...
...
</ListView>
...
...
</Border>
...
...
</Grid>
</Grid>
</Window>
This is all in a form that is resizable. Therefore, the ListView should also resize but it should do that only when user resizes the form. The problem with my hard coded value above is obvious, the ListView will not resize but stay at constant height=370.
I know I can set this to 370* but in that case, my List will resize to fit all items. I want to limit this so that resizing only occurs when user resizes the form. So, ListView should show scroll bars if there are more items and as the user resizes form, that scroll bar should go away if form is resized to height that can accommodate all items in ListView.
UPDATE:
Instead of hard coding the height to 370 above, I have tried setting the height to , Auto, and 370. All of these would expand the ListView (and therefore form, too) to accommodate all items in the ListView.
UPDATE 2:
Updated XAML to show whole tree structure.
UPDATE 3:
As per Rachel's suggestion, set hardcoded 370 to "*" in commented line above in XAML and that produces form resized so that the ListView fits all items in it. I added screenshot showing the form as it opens and a screenshot showing how it should look like when it opens. As you can see, it resizes hightwise to accomodate all itesm.
What I need is that form and ListView stay in their set size and resize only if user resizes the form.
If I understand your question correctly, you are saying the form loads as too large of a size because the ListView is growing to it's full height. If that's the case, remove the SizeToContent="Height" from the <Window> tag since it is making the window's initial height be equal to whatever height the content is, which includes the fully sized ListView.
By setting ScrollViewer.VerticalScrollBarVisibility="Visible" & MaxHeight="700"
scroll bar will be visible
MaxHeight to any value
Hi I think i have understand you. So, i am trying:
So, you want to have your ListView at least a height of 370 and then only resizes if the window resizes (increment and decrement of window size).
Setting MinHeight of 2nd RowDefinition could help
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition MinHeight="370"/> <!-- THIS IS HARDCODED....-->
</Grid.RowDefinitions>
.....
</Grid>
Thank you.

WPF calculate Parent margin based on child control position

I have following XAML. I have to set margin to CanvasRuler as per child control (LabelEditFrame) Left position. How do I do that.
<wpfcommon:CanvasNavigationBar>
<DockPanel>
<wpfcommon:CanvasRuler /> <!-- Horizontal -->
</wpfcommon:CanvasRuler /> <!-- Vertical -->
<border>
<StackPanel>
<wpfcommon:LabelEditFrame>
</ wpfcommon:LabelEditFrame>
</StackPanel>
</border>
</DockPanel>
</wpfcommon:CanvasNavigationBar>
Right now I have this
I want to have this (I can do that by setting hard coded value, but I need to set it dynamically, so if position of child control gets changes, it will change ruler position automatically).
From my experience, if this is on a Canvas and are children on a canvas, you can use the
Canvas.SetLeft
and
Canvas.SetTop
methods.
So for the Rulers, you can set the:
VerticalAlignment="Top", HorizontalAlignment="Left
Then when the LabelEditFrame is moved (whichever event you use to trigger that), you can adjust the two rulers with something like this:
Canvas.SetLeft(HorizontalCanvasRuler, LabelEditFrame.Margin.Left);
Canvas.SetTop(VerticalCanvasRuler, LabelEditFrame.Margin.Top);
I haven't tried this out, but I have used to adjust controls like this before so it should work :)
I suggest you to put all that stuff to Grid and allow it calculate anything for you:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="SomeFixedHeightToGetTopMargin"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="SomeFixedWithToGetLeftMargin"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<wpfcommon:CanvasRuler Grid.Column="1"/>
<wpfcommon:CanvasRuler Grid.Row="1"/>
<Border Grid.Row="1" Grid.Column="1">
<StackPanel>
<wpfcommon:LabelEditFrame/>
</StackPanel>
</Border>
</Grid>

Wpf Resize object with window

Looked around to find a way to resize bind with the windows resize without explicitly telling my object to grab the windows size.
Here is the code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WindowsFormsHost Background="{x:Null}" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Name="windowsFormsHost1" VerticalAlignment="Top" Margin="-1,0,0,0">
<wf:Panel x:Name="pnlLivePreview" />
</WindowsFormsHost>
</Grid>
This was followed by the example showed here
Edit: Question: Why doesn't panel resize with the window ?
Simply remove the explicit Width and Height settings, and the HorizontalAlignment and VerticalAlignment settings, thus:
<WindowsFormsHost Background="{x:Null}"
Name="windowsFormsHost1"
Margin="-1,0,0,0">
<wf:Panel x:Name="pnlLivePreview" />
</WindowsFormsHost>
I'm going to throw a wild guess here, but since this is a WinForms panel, try setting it's Dock property to Fill thus:
<wf:Panel x:Name="pnlLivePreview" Dock="Fill" />
Really not sure it would work, if it doesn't work in markup, try doing it in code.
Bind your Height/Width to your window's height/width
<Window x:Name="Root_Window">
<Grid Height="{Binding ElementName=RootWindow, Path=ActualHeight}"
Width="{Binding ElementName=RootWindow, Path=ActualWidth}">
<!-- Content Here -->
</Grid>
</Window>
The answer: Problem is not the panel but the api used to create the content of it.

Resources