Dynamic size canvas with Scroll bars - wpf

I am developing a simple WPF application without any auto layout. The goal is when a user clicks (mouse down) a element (say textBlock) will appear at the location of the mouse click. For this I am using canvas panel embedded in a Grid of 1 row, 1 column and scrollviewer (visible). The issues are:
1. when the application window is resized the scroll viewers do not become active.
2. I want the ability to auto grow the canvas with mouse drag. Something like in MS-Excel when user drags the mouse horizontally/vertically the canvas should grow.
I have searched net a lot to figure this out and am unable to get an answer. Any help in this regard would be great.
Thanks a bunch in advance.
-P

I after asking this question I figured it out how to have freeform layout and autosize. Here is a sample XAML if anyone needs it or has better suggestion to improve this:
<Ellipse Grid.Column="0" Fill="Red"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<!-- Creating a grid with one row and one column"-->
<ScrollViewer x:Name="ServerLiistCanvasScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="Auto" Width="Auto"
Grid.Column="2" >
<Grid x:Name="drawingGrid" Grid.Column="2"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="Pink"
MouseDown="handleCanvasMouseDown">
</Grid>
</ScrollViewer>
</Grid>

Related

Prevent Scrollviewer from stopping in the middle of an element

I'm developing a touch application that uses a ScrollViewer and a StackPanel to make a carousel of images. The images are added to the stackpanel and the user slides them using fingers.
The problem is that I'm having a visual problem, what I want is to prevent the scrollviewer from stopping in the middle of two images. Just like this:
The idea is: when the inertia is stopping, automatically scroll to the nearest image.
Thats my XAML:
<ScrollViewer x:Name="crlGalleryPlayer1" Panel.ZIndex="303" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" PanningMode="HorizontalOnly"
PanningDeceleration="0.01" PanningRatio="1"
ManipulationBoundaryFeedback="crlCarrusel_Viewer_ManipulationBoundaryFeedback"
IsManipulationEnabled="True" Width="1920" Height="1080" Margin="0,0,0,0" CanContentScroll="False" Visibility="Hidden">
<StackPanel Name="pnlCarrusel_ViewerPlayer1" Visibility="Visible"
ScrollViewer.IsDeferredScrollingEnabled="False" IsManipulationEnabled="True" Margin="0,0,0,0"
Orientation="Horizontal" Panel.ZIndex="303">
</StackPanel>
</ScrollViewer>
I've tried to start from the ManipulationCompleted event of the Scrollviewer but it's not getting fired, only ManipulationStarted
Thank you all.

ScrollViewer Focus Error in WPF in Code behind

To create a circle below each time the button is clicked. In canvas
position of Circle move to out of canvas.
But, Scroll viewer does not move up and down.
<ScrollViewer x:Name="scv" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Margin="135,0,0,0" Focusable="True">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="373" VerticalAlignment="Top" Width="685" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True"/>
</ScrollViewer>
Is there a way to move up and down the scroll Viewer?
edit
An attempt was made to try to use the code to the link to me the site, an error occurs
don't use code... Anything simple way?

Silverlight Scrollviewer Mousewheel scrolls only when scrolled on datagrid. Page doesn't scroll when scrolled outside the datagrid

Page scrolls without any issue when the mouse is over data grid. If the mouse outside datagrid page doesn't scroll.
<navigation:Page>
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer x:Name="scrollMainQueue" VerticalScrollBarVisibility="Auto" >
<StackPanel>
<StackPanel>
</StackPanel>
.......
<StackPanel>
<data:DataGrid AutoGenerateColumns="False" Name="grdWorkingDocs" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="50" Margin="5,0,5,5" CanUserResizeColumns="False" CanUserReorderColumns="False" LoadingRow="grdWorkingDocs_LoadingRow" AlternatingRowBackground="White" RowBackground="White" HorizontalGridLinesBrush="White" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" />
</StackPanel>
</StackPanel>
......
</StackPanel>
</ScrollViewer>
</Grid>
scrollMainQueue.SetIsMouseWheelScrollingEnabled(true);
After some research Got the answer.
Basically we need to set the background color to the scrollviewer. It worked after that.
<ScrollViewer x:Name="scrollMainQueue" VerticalScrollBarVisibility="Auto" Background="White">
Answer is as mentione above. Applied background color to scrollviewer made is scrollable.
Background="Transparent" also works, if you can't use any color because of your design requirements.
I was using the Content Control to hold the inner view wrapped up with scroll viewer, the scroll viewer was only working on mouse wheel when the pointer is on any field and not on the empty area.
After seeing the above posts, I set the background color and it started working fine, though the solution looks unrelated [don't know how exactly related to the problem].

TabControl width increases on adding tabs

My application UI is divided in 2 parts. Left side is Navigation Menu and Right is View Area where the selected Menu content is displayed. Now, one of the menu is reports. I am using Tabcontrol with Header and Content Template. Template has a ViewModel as DataType and content as the respective View which is a UserControl. This TabControl is inside a scrollviewer which is set as horizontal and vertical alignment to stretch.
The user control hosts a ContentPresenter inside a Grid which is bound to a ReportHost which has a reportviewer as child. I am using this ReportViewer to generate reports.
When the user opens a report, it opens in a new tab. It works fine till the number of tabs is such that the tabheaders are contained inside the viewing area. But as soon as more tabs are added, it causes the tabcontrol width to stretch, causing the content area of the tab to stretch and the contentpresenter also stretches causing horizontal scroll to appear.
This finally result in the report to stretch and due to some reason, unknown to me, the report overlaps the Navigation Area of the UI, as if it is not a part of the UI but is overlapping it. The whole report keeps on floating on top of the View Area and Navigation menu on scrolling.
I can fix it by providing the MaxWidth to the ScrollViewer but I don't want to do that. I would like the width of the tabcontroll or the Scrolviewer to be decided purely based on available View Area. How do I do this through the code or XAML without using fixed width.
I am not sure if I was able to explain the situation. Please let me know if more information or clarification is needed. I would be more than happy to provide details.
Edit: Adding Code for information.
<DataTemplate x:Key="TabContent" DataType="{x:Type VM:ReportViewModel}">
<View:Report/>
</DataTemplate>
<DataTemplate x:Key="TabHeader" DataType="{x:Type VM:ReportViewModel}">
<ContentPresenter Content="{Binding Path=TabHeader}"
VerticalAlignment="Center"/>
</DataTemplate>
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap"
Text="Reports" VerticalAlignment="Top" Margin="10,13,0,0"
FontSize="18.667" FontFamily="Segoe UI" Foreground="White"/>
<Border BorderThickness="0" Margin="0,50,0,0"
Background="{DynamicResource Brush_HeaderNew}" Height="50" Width="Auto"
VerticalAlignment="Top"/>
<TabControl ItemsSource="{Binding ReportItems}" Grid.Row="1" Margin="0,20,0,0"
SelectedItem="{Binding SelectedReportItem}"
ContentTemplate="{StaticResource TabContent}"
ItemTemplate="{StaticResource TabHeader}"
/>
</Grid>
</ScrollViewer>
ScrollViewer presents to its child an infinitely large area on which to set itself out, because it reasons that it can just offer scrolling if it's bigger than the space available to ScrollViewer itself. Because yours has scrolling enabled in both directions, that means the TabControl can expand as much as it likes in either direction, and it's not going to be smart enough to know that it's inside a ScrollViewer and that you want the tabs to not take advantage of this virtual space.
From the sound of things, you might want to consider moving the ScrollViewer within the TabControl so that only the contents of the tab is scrollable rather than the whole set. You should be able to do that by modifying the tab content template.

GridSplitter is hidden by WinForm element

I am working in a WPF application. And my problem is regarding the GridSplitter visiblity.
In my xaml code,I am maitaining a Grid. In the 3rd row of Grid, I am hosting a Winform DataGridView. In the same row, the GridSplitter is written.
When GridSplitter is dragged to adjust Grid Row sizes, for other controls like Buttons etc it is properly visible.
But when it comes over the DataGridView which I am hosting, the GridSplitter hides behind the hosted control.
In fact, whatever I host instead of Datagridview,makes the GridSplitter hide behind it, when it is dragged.
I tried setting the ZIndex for GridSplitter. It did not make any difference.
Can anyone help me with this?
Following is my XAML sample code:-
<Grid>
<Grid.RowDefinitions>
<RowDefinition Name="rowForButton"/>
<RowDefinition Name="rowForGridSplitter" Height="Auto" MinHeight="81" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Height="50" Width="110" Content="Button in First Row"/>
<my:WindowsFormsHost Panel.ZIndex="0" Grid.Row="1" Margin="30,11,138,0" x:Name="winHost" Height="58" VerticalAlignment="Top" OpacityMask="Transparent">
<win:DataGridView x:Name="dataGridView"></win:DataGridView>
</my:WindowsFormsHost>
<GridSplitter BorderThickness="1" Panel.ZIndex="1" Grid.Row="1" HorizontalAlignment="Stretch" Height="5" ShowsPreview="True" VerticalAlignment="Top">
</GridSplitter>
</Grid>
Thanks.
Unfortuantely the WinForms control will always sit on top of your WPF elements, it does the same when you try and scroll it. The best way to work around it is to put the required logic for sizing/scrolling/whatever the WinForms part into a WinForms control, then host that control in the WPF form.
Your Grid has only 2 rowdefinitions but needs 3. At the moment the WindowsFormsHost and the GridSplitter are sharing the second row (i.e. Grid.Row="1"). Presumably you want the WindowsFormsHost to use Grid.Row="2".

Resources