DevExpress LayoutSplitter and DockLayoutManager drag and drop issue - wpf

I am having some some problems using the LayoutSplitter and DockLayoutManger from DevExpress.
dxdo:DockLayoutManager>
<dxdo:DockLayoutManager.LayoutRoot>
<dxdo:LayoutGroup Orientation="Vertical" Height="*">
<dxdo:LayoutGroup Orientation="Vertical" Height="*">
<dxdo:DocumentPanel>
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding SomeViewModel}" ContentTemplateSelector="{StaticResource templateSelector}"/>
</Grid>
</dxdo:DocumentPanel>
</dxdo:LayoutGroup>
<dxdo:LayoutGroup Height="Auto" Orientation="Vertical">
<dxdo:LayoutSplitter/>
</dxdo:LayoutGroup>
<dxdo:LayoutGroup>
<dxdo:LayoutPanel Height="Auto" AllowDock="True">
<ItemsControl ItemsSource="{Binding SomeViewModel.SomeCollection}" ItemTemplateSelector="{StaticResource templateSelector}">
</ItemsControl>
</dxdo:LayoutPanel>
</dxdo:LayoutGroup>
</dxdo:LayoutGroup>
</dxdo:DockLayoutManager.LayoutRoot>
</dxdo:DockLayoutManager>
The LayoutSplitter isn't moving up and down. It just remains static.
With the DockLayoutManager, the 3rd nested LayoutGroup, when I remove a component from it, I can't drop the component back in. A hint would be great thanks!

The LayoutSplitter control is needed to split layout groups or layout control items. It can't be used with LayoutPanels or DocumentPanels. Moreover it is not needed to use splitters with dock items because these items resizing are automatically provided by the DockLayoutManager. You should also use the DocumentPanel as child item for the DocumentGroup instead of placing that document directly to the LayoutGroup.Items collection. Or use the LayoutPanel instead of the DocumentPanel.
So, you markup should looks like this:
<dxdo:DockLayoutManager>
<dxdo:LayoutGroup Orientation="Vertical" >
<dxdo:DocumentGroup>
<dxdo:DocumentPanel Caption="Document">
<!-- Document content -->
</dxdo:DocumentPanel>
</dxdo:DocumentGroup>
<dxdo:LayoutGroup>
<dxdo:LayoutPanel Caption="Panel">
<!-- Panel content -->
</dxdo:LayoutPanel>
</dxdo:LayoutGroup>
</dxdo:LayoutGroup>
</dxdo:DockLayoutManager>
You can read more in these articles:
Dock Layout Manager Fundamentals
Layout Groups
Dock Items
Layout Items
Document Groups and Panels

Related

WPF XAML treeview in a stack panel - no scrolling?

so I have a TreeView control in my XAML. It works fine. If I extend the treeview to be larger than the user control it resides in, I get a scroll bar, which is good. However, inside this user control I want some other things. So I put the treeview in a stack panel with some other things, and this time I don't get the scroll bar if the treeview expands to be larger than the user control it's in.
Is this something other people have come across, and is there a fix for it?
Embed your stackpanel inside a ScrollViewer: stackoverflow.com/a/6250287/7517676. You also might have to explicitly set VerticalScrollBarVisibility and HorizontalScrollBarVisibility, depending on your need.
Here's a code sample:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel ... />
</ScrollViewer>
Based on this answer a StackPanel isn't the right container for a TreeView, but a Grid is. So this will enable scrolling inside the TreeView, by mouse and scrollbar:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label>Some descriptive label.</Label>
<TreeView Grid.Row="1" ItemsSource="{Binding SomeSource, Mode=OneWay}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MyNodeType}" ItemsSource="{Binding Children}">
<Label Content="{Binding NodeName}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>

Force expander to take all available space

I got something like:
1) <grid> with some rows -> 2) <stackPanel> -> 3) Expander -> 4) Expander content...
..and I can't force expander content to be stretched as long and as wide as possible by currently free space in the given grid.row (#1). Whatever I try, expander keeps using to take minimum necessary space to renders its content. But if I do something like MinHeight=500, then it's OK.
P.S. I had an idea to hack it. Just to create transparent line, stretched through the row, and then bind expander height to the actual height.. but it seems ugly to me. Maybe someone knows another way?
<Grid Name="GlobalPanel" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="0.7*" />
<RowDefinition Height="0.3*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
<Expander Name="MainExpander"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<!-- HERE EXPANDERS CONTENT WHICH I WANT TO BE STRETCHED -->
</Expander>
</StackPanel>
</Grid>

scrollviewer the property 'content' is set more than once

Here my code:
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer
Grid.RowSpan="2" Style="{StaticResource HorizontalScrollViewerStyle}"
HorizontalScrollBarVisibility="Visible" >
<!-- The elements you want to be horizontally scrollable goes here -->
<!-- Horizontal scrolling grid used in most view states -->
<GridView
Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Padding="100,136,116,46"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick"/>
<Button Hello /> <!-- From here come the Error -->
</ScrollViewer>
</Grid>
When I add any thing after my GridView, it give me that error (the property content is set more than once).
The answer is right there in the error message. A ScrollViewer can only have one child (you have two, a GridView and a Button). If you want to add multiple things, you will have to wrap them in a panel that allows multiple children (e.g. Grid).

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.

wpf layout help

I have the following xaml which resides in a wpf user control -
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBox
x:Name="MyTxt"
TextWrapping="WrapWithOverflow"
Grid.Row="0"
/>
<ListView
x:Name="MyList"
ItemsSource="{Binding}"
Grid.Row="1"
/>
<Label
Grid.Row="2"
/>
</Grid>
This control is nested within a grid in a view. I would like to have the text box be a set height at the top of the grid, the label at the bottom showing as a fixed height at the bottom of the grid. I want the list view to fill the rest of the screen area.
The problem that I am having is the listview does not size correctly. If I have too many records that show up in it, it extends beyond the window and no scroll bars are available to scroll down. I therefore cannot get to the bottom to see the vertical scroll bar if the data stretches off to the right of the screen.
I was able to set the listview to a fixed height and that worked, but I would like it to be more dynamic and resize with the window if possible.
Does anyone have any tips that might get the sizing correct?
Thanks for any thoughts.
EDIT - Here is the xaml for the containing grid in the mainwindow view. this was adapted from the article by Josh Smith here
<Grid>
<Border
Style="{StaticResource MainBorderStyle}"
>
<HeaderedContentControl
Content="{Binding Path=Workspaces}"
ContentTemplate="{StaticResource WorkspacesTemplate}"
/>
</Border>
</Grid>
I do have the scrollviewer properties set as mentioned in some of the answers below.
Here is the datatemplate for the workspace
<DataTemplate x:Key="WorkspacesTemplate">
<TabControl
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource ClosableTabItemTemplate}"
Margin="4"
/>
</DataTemplate>
Can you just add these properties to the listview?
ScrollViewer.CanContentScroll = "True"
ScrollViewer.VerticalScrollBarVisibility="Visible" <!-- or "Auto" -->
Everything else looks ok to me. You have the 3 rows, 2 of which are absolute, the other stretching. You also have the listview in the 2nd row, so it should stretch with it.
if that doesn't work, try wrapping the ListView in a scrollviewer
<ScrollViewer>
<ListView/>
</ScrollViewer>
What is the VerticalAlignment of a ListBox by default? You might need to set the vertical alignment to Stretch.
<ListView
x:Name="MyList"
ItemsSource="{Binding}"
Grid.Row="1"
VerticalAlignment="Stretch"
/>
I was able to get it working. If I change the containing grid in the main window to use a ContentControl instead of a HeaderedcontentControl, it works as expected.
Thank for any help.

Resources