Pinned item inside silverlight scrollviewer - silverlight

Is there a way to have a control inside silverlight scrollviewer that does not scroll? For example I would like the similar behavior as you get when pinning a column in a datagrid so that I can have a footer to my listbox but still have it fit inside the scroll bars (looks better that way). here is a screen shot of what I have. The control I want inside is at the bottom.
Per request here is my control template for the listbox. I have a template for scrollviewer to but could not find a way to tell it to leave the border at bottom when scrolling everything else. If you look at the template I have the border outside of the scrollviewer to keep it from being scrolled but would like it to fit inside the scrollbar because I think it looks better.
<ControlTemplate TargetType="telerik:RadListBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border BorderThickness="0" Background="{StaticResource ListBoxBackground}" Grid.RowSpan="2">
</Border>
<ScrollViewer x:Name="PART_ScrollViewer"
Margin="0"
IsTabStop="False"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
TabNavigation="{TemplateBinding TabNavigation}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Style="{StaticResource ScrollViewerStyle}">
<ItemsPresenter/>
</ScrollViewer>
<Border Grid.Row="1" Background="Transparent" BorderBrush="Tan" BorderThickness="1" Height="50">
<TextBlock Text="Dont scroll but keep in scrollviewer" TextWrapping="Wrap"/>
</Border>
<ContentPresenter x:Name="dragVisualPlaceholder" Visibility="Collapsed" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</ControlTemplate>

Related

WPF: GridSplitter not visible but functions as expected

I am creating a new WPF Application where the main window has a grid inside a dock panel. The grid will have 3 columns and one row, out of which the middle column is dedicated for the GridSplitter. The other two columns have a dock panel each, which will have any content (to be created in run-time). My problem is that despite multiple approaches to make the GridSplitter visible, I have not been successful.
I have even followed tips given in this How To page in Microsoft documentation, but to no fruition:
https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/how-to-make-sure-that-a-gridsplitter-is-visible
Here is my XAML code:
<Window
...
Height="600"
Width="650">
<DockPanel LastChildFill="True">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DockPanel Name="LeftDockPanel" Grid.Column="0" LastChildFill="True" Width="350" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="LightCyan">
</DockPanel>
<DockPanel Name="RightDockPanel" Grid.Column="2" LastChildFill="True" Width="300" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Azure">
</DockPanel>
<GridSplitter Width="5" Background="Red" Grid.Column="1" BorderBrush="Red"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="3,0,3,0" ResizeBehavior="PreviousAndNext" Panel.ZIndex="1"/>
</Grid>
</DockPanel>
</Window>
I've attempted the following with my code:
Assigned a ZIndex=1 to the grid splitter while it shares a column with the LeftDockPanel
Dedicated a column explicitly for the splitter, assigning it a width
Ensured that the GridSplitter is the last control added to the grid
Combination of 2, 3 and 4 - As you see in the code.
On hovering the mouse in the appropriate area, the cursor does change to expose the gridSplitter, but it is never visible. Even the resizing actions are working as expected.
What am I missing or doing wrong that the GridSplitter is not visible?
Your issue is not reproducible. Maybe you have defined an implicit Style somewhere. Try to set the Template property to a custom template:
<GridSplitter Width="5" Background="Red" Grid.Column="1" BorderBrush="Red"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Margin="3,0,3,0" ResizeBehavior="PreviousAndNext">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"/>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>

How do I remove the Mouse Over Effect on WPF Ribbon Group?

I'm working on this Ribbon Control in WPF: System.Windows.Controls.Ribbon.Ribbon
I've made the background orange and I've changed the style slightly. It looks like this:
When I move the cursor over a group it looks like this:
I want to remove the white mouse over / hover effect, but I don't know which Style or Template I should look at. I've tried all these:
Ribbon
RibbonTab
RibbonTabHeader
RibbonButton
RibbonGroup
Is it possible? How do I do it?
So it is inside the style of the RibbonGroup:
<!--Ribbon Group - Style-->
<Style TargetType="RibbonGroup">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="ribbonGroupControlTemplate" TargetType="RibbonGroup" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border Background="{TemplateBinding Panel.Background}" Name="GroupBorder" Margin="1,2,0,0">
<Grid Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" MinHeight="16" />
</Grid.RowDefinitions>
<Border BorderThickness="1,1,1,1" CornerRadius="2,2,2,2" BorderBrush="{TemplateBinding RibbonControlService.MouseOverBorderBrush}" Background="{TemplateBinding RibbonControlService.MouseOverBackground}" Name="PART_HotBackground" Opacity="0" SnapsToDevicePixels="True" Grid.RowSpan="3" />
<Border Background="{TemplateBinding Border.BorderBrush}" Name="SeparatorBorder" Width="1" Height="75" VerticalAlignment="Center" SnapsToDevicePixels="True" Grid.Column="1" Grid.RowSpan="3" />
<Border Padding="3,0,3,0" Margin="2,1,2,0">
<Grid>
<ItemsPresenter Name="ItemsPresenter" />
<ContentControl Name="PART_TemplateContentControl" Visibility="Collapsed" Focusable="False" />
</Grid>
...
The culprit is this Border:
<Border BorderThickness="1,1,1,1" CornerRadius="2,2,2,2" BorderBrush="{TemplateBinding RibbonControlService.MouseOverBorderBrush}" Background="{TemplateBinding RibbonControlService.MouseOverBackground}" Name="PART_HotBackground" Opacity="0" SnapsToDevicePixels="True" Grid.RowSpan="3" />
When I comment out or remove that border and the triggers that go with it; it solves my problem.

How to get TabPanel ActualWidth from TabControl

I have a tabcontrol and tab strip placement is on left. So it is a simple navigation menu type tab control.
There is a TabPanel inside TabControl's control template.
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="Grid" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" Padding="{TemplateBinding Padding}" Margin="0,-1,0,0">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ScrollViewer x:Name="scroll" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" Template="{StaticResource ScrollViewerTab}">
<TabPanel x:Name="HeaderPanel" IsItemsHost="true" Margin="0,2,0,0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" VerticalAlignment="Bottom" />
</ScrollViewer>
</Grid>
</ControlTemplate>
I need TabPanel's (tab headers) ActualWidth outside tabcontrol for alignment purposes.
I tried following but it did not work.
<TextBlock Text="{Binding Path=Actualwidth, ElementName=HeaderPanel}" />
<TabControl />
I also tried to bind the ActualWidth of header panel to Tag property of TabControl. Even that did not work.
<TabControl Tag="{Binding Path=ActualWidth, ElementName=HeaderPanel}" />
TabControls.Items collection gives the list of ViewModel objects. So I cannot get TabItem instances.
I ended up using visual tree helper in the codebehind file
var tabPanel = VisualTreeHelpers.FindChild<TabPanel>(TabControl, "MenuPanel");

How do i make a WPF tab control's tab area smaller than the control?

I have a scenario where i have two buttons in the top right of my application, and i have a tab control that spans the entire application's screen. (Basically the two buttons are on the same horizontal line as the tabs in the tab control). The problem is that when i have multiple tabs open, the buttons and the tabs overlap. I don't want to have to specify the grid row/column numbers so that the buttons are above the tabs.
Is there any way to specify to the Tab control a certain area that it has to open tab controls before it automatically starts a second row of tabs?
In other words, if my tab control has a width of X, how can i tell the area that displays the actual tabs that it should only occupy say, x-15 amount of space.
Thanks!
You'll have to supply the ControlTemplate for the TabControl to do that. Here is an example where 100 pixels is reserved to the right of the header panel:
<Grid>
<TabControl>
<TabControl.Template>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local"
SnapsToDevicePixels="true"
ClipToBounds="true">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1"
Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0"
Height="Auto"/>
<RowDefinition x:Name="RowDefinition1"
Height="*"/>
</Grid.RowDefinitions>
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
<Border x:Name="ContentPanel"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2"
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="2">
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent"/>
</Border>
</Grid>
</ControlTemplate>
</TabControl.Template>
<TabItem Header="Item1"/>
<TabItem Header="Item2"/>
<TabItem Header="Item3"/>
<TabItem Header="Item4"/>
</TabControl>
</Grid>
Resize the window to see it in action.

masking in WPF template (opacitymask reversed)

I am currently redoing a groupBox's template.
I would like the header to have rounded corner on top and "inverted" rounded corner at the bottom:
I managed the above template quite easily by rounding the top corners of the content part and putting the content on top of a "background" container having the darkest color as background.
BUT...
my specifications require that the content's background (lightgray on the picture) might be transparent (i.e.: it should be possible to see right through the content part without having to loose the header's background color). And this is where I'm stuck...
I could easily split this control into two rows of a grid, one for the header, the other for the content and have pretty rounded corner at the top, but I would not be able to get those "inverted" rounded corner at the header's bottom, would I?
so I would be really glad if somebody could either:
point me to a solution (involving whatever dirty trick)
confirm that what I want to do is impossible
thanks in advance
You could use a Path to obtain what you want, a Path that describes the whole dark gray area of your header. You can look at the examples here and figure out the data for your Path.
I figured it out, using the path option submitted by Andrei.
for those interested, here is the final template (using a cornerRadius of 3):
<Border x:Name="Border"
CornerRadius="3"
Background="{TemplateBinding local:MyGroupBox.ContentBackground}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3"/>
<ColumnDefinition/>
<ColumnDefinition Width="3"/>
</Grid.ColumnDefinitions>
<Border x:Name="HeaderBorder"
Grid.Row="0"
Grid.ColumnSpan="3"
CornerRadius="3,3,0,0"
Background="{TemplateBinding Background}" />
<ContentPresenter Grid.Row="0"
Grid.ColumnSpan="3"
Margin="6"
ContentSource="Header"
RecognizesAccessKey="True"
HorizontalAlignment="Center"/>
<Path x:Name="LeftCorner"
Grid.Row="1"
Grid.Column="0"
Stretch="Fill"
Data="M0,0 L3,0 C1.3431457,0 0,1.3431457 0,3 L0,0 z"
Fill="{TemplateBinding Background}"/>
<Path x:Name="RightCorner"
Grid.Row="1"
Grid.Column="2"
Stretch="Fill"
Data="M0,0 L3,0 3,3 C3,1.3431457 1.6568543,0 0,0 z"
Fill="{TemplateBinding Background}"/>
</Grid>
</Border>
Perhaps that top area contains two borders?
<Border Background="Gray"
Height="{TemplateBinding CornerRadius,
Converter={StaticResource ExtractHeight}}">
<Border Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius,
Converter={StaticResource UseTop}}" />
</Border>
Your lower area would have something similar in a Border with just the bottom corners in the CornerRadius property.

Resources