Border over selected cells - wpf

I'm trying to have a yellow border just over the top of my grid cells minus the first two cells(home button and search). I've tried a couple scenarioes.
This is the application header without any borders.
http://snag.gy/2lIIm.jpg
This is the application when I specified borders over the grid items. The problem with this is that it stops and doesn't extend to the end.
http://snag.gy/pVbHd.jpg
The picture below extends to the end but it's also ontop of item 1 and 2. I'm trying not to have a border on the first two items.
http://snag.gy/6QiX9.jpg
If I can possibly get help with this issue please.
WorkTabView.xaml
Border over selected buttons but not extended to the far right - Pseudo Code
<Grid>
....
<Button-Home Grid.Column0>
<AutoCompleteBox Grid.Column1>
<Border BorderBrush="Yellow" Grid.Column=2 BorderThickness="0,1,0,0">
<Button1/>
<Border/>
<Border BorderBrush="Yellow" Grid.Column=3 BorderThickness="0,1,0,0">
<Button2/>
<Border/>
<Grid>
Border over everything, but my goal is not to have over search and home button Pseudo Code
<Border BorderBrush="Yellow" BorderThickness="0,1,0,0">
<Grid>
....
<Button-Home Grid.Column0>
<AutoCompleteBox Grid.Column1>
<Button1 Grid.Column2/>
<Button2 Grid.Column3/>
<Grid>
</Border>
Sorry for Pseudo code, posted it to prevent lengthy post and repetitions. My goal is to have the border around everything BUT the search and yellow home button.

I see two options here.
Use your Option1, but place an extra item to fill the rest of the remaining space.
<Grid>
....
<Button-Home Grid.Column0>
<AutoCompleteBox Grid.Column1>
<Border BorderBrush="Yellow" Grid.Column=2 BorderThickness="0,1,0,0">
<Button1/>
<Border/>
<Border BorderBrush="Yellow" Grid.Column=3 BorderThickness="0,1,0,0">
<Button2/>
<Border/>
<Border BorderBrush="Yellow" Grid.Column=3 BorderThickness="0,1,0,0">
<SomeBlankItemToTakeUpRemainingSpace/>
<Border/>
<Grid>
If this is used, I would definitely see about creating a custom style or template for the border to avoid repeating myself
Alternatively, split the two sections up into two separate panels, and store them in another panel that has the default behavior of filling all available space, like the DockPanel
<DockPanel>
<Grid DockPanel.Dock="Right">
<HomeButton>
<SearchBox>
</Grid>
<Border> <!-- this is last item in DockPanel, so should stretch to fill all available space -->
<Grid>
<Button1 Grid.Column1/>
<Button2 Grid.Column2/>
<Grid>
</Border>
</DockPanel>
Personally I prefer the second option. LayoutControls in WPF are meant for laying out your controls, not for creating tables of items, so to me this seems like the cleaner approach.

Related

border set like stack of cards

I am wondering what the best way is solve this problem I have a text block with an image around a border and I can add properties and I want to add a border around it to be like a stack of cards. I'll demonstrate what I mean with pictures. The first picture I have is what displays just now.
The second picture is what I want it to display if there is properties added in this example there would be 5 added properties.
Use many borders that overlap, with a non transparent background.
The xaml appearing order is the painting order.
So the last components appear over the first ones.
All the components are in a grid that allow many children.
<Grid>
<Grid.Resources>
<system:Double x:Key="width1" >100</system:Double>
<system:Double x:Key="height1" >30</system:Double>
</Grid.Resources>
<Border BorderThickness="1" BorderBrush="Gray"
Background="White"
Margin="120 80 0 0"
Width="{StaticResource width1}"
Height="{StaticResource height1}" />
<Border BorderThickness="1" BorderBrush="Gray"
Background="White"
Margin="110 90 0 0"
Width="{StaticResource width1}"
Height="{StaticResource height1}" />
<TextBlock Text="+6"
Padding="20 7 0 0"
Margin="100 100 0 0"
Background="Gray"
Width="{StaticResource width1}"
Height="{StaticResource height1}"/>
</Grid>
Note : the use of resources for setting same size to all components
Regards

Adding a 'Load More' button below ItemsControl in windows phone 8.1 Silverlight application

I am implementing a RSS reader application and i am using ItemsControl to display the news items. I tried to add a 'Load More' button below the ItemsControl like this
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ItemsControl x:Name="itemsControl" Margin="10,10,10,0" Grid.Row="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel>
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
<TextBlock x:Name="loadMoreTextBlock" Grid.Row="1" Text="Load more"/>
</Grid>
But the textblock is not displayed in the end of the scrolling and it is always visible in the root grid. I want to display the 'Load More' text only at the end of the itemscontrol as the user scrolls down to bottom.
Changing the ItemsControl.Template like this
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<StackPanel>
<ItemsPresenter />
<TextBlock x:Name="loadMoreTextBlock" Text="Load more"/>
</StackPanel>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
solves the problem, but the performance of the ItemsControl is poor. Do you have any better idea or suggestions?
Thanks
Vinoth Selvaraj
I've spent at least 2 hours figuring out why virtualization is lost in this scenario, but the only way I managed to get around this problem is by sticking to the ControlTemplate you provided first ->
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
and making sure that you put the 'Load more' item into your viewmodel's collection that you bind your ItemsSource to. In this case you might need to apply a different ItemTemplate to the last member of the list, that can be achieved via a custom DataTemplateSelector.
However, when clicking 'Load more' you would have to relocate this special list item to the end of the list again.
On the whole, I'd suggest going for the 2nd approach you proposed, i.e. place 'Load more' below the list OR maybe consider changing the whole concept and use some kind of paging mechanism, whereas you can only see the first few hundred entries in the list and pressing some buttons shows the previous / next few hundreds.

Double Border with a VisualBrush in WPF

I'm curious if anyone knows of a way to easily get a double border effect in WPF similar to what you see in the selected items in Windows Explorer in Windows 7.
If you look closely, you'll notice that the selected item has a dark border, a lighter, inner-border, and then a gradient background.
Currently, I'm using two borders around an object any time I want to achieve this effect. Doing it that way is ugly syntactically and really muddies my view xaml. Being a web developer at heart I'd like to separate the xaml structure from the style as much as possible. So, I've started putting this into Styles and Content Templates in order to pull it out of my view xaml.
However, I'm curious if there may be a better way to go about this.
I played around for a while using a VisualBrush as a background to try to get the effect. However, I want to be able to apply the background to elements that can be any size and the way the VisualBrush stretched the visual to fit the element background didn't work the way I wanted it to. Essentially, I'd really just like it to stretch the visual the way the WPF layout system would do it.
Any ideas would be greatly appreciated.
--
Dusty
A VisualBrush is probably not what you want to do in this scenario, as it's pretty heavy.
You can solve the problem with some Xaml without nesting borders.
For example,
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="This is some text" VerticalAlignment="Center"/>
</Grid>
</Border>
You can, of course, tweak the properties to get the look you need.
EDIT: If you want to create a style, so you can reskin the look-and-feel, you can do something like this:
<Window.Resources>
<Style x:Key="BorderedTextBlock" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ContentControl Style="{StaticResource BorderedTextBlock}" Content="This is some text" Width="200" Height="24"/>
</Grid>
Additionally, turn this into a custom control with all the styling and theming parameters that you need.
Hope that helps,
Sergio

How to place a ScrollViewer on top of the content it should scroll

I would like to put my ScrollViewer in such a way that it overlaps/sits on top of the content it scrolls. I would set the Opacity of the ScrollViewer so that the content is visible underneath.
As far as I understand the default ScrollViewer, this doesn't seem to be possible out of the box since the content is nested inside the ScrollViewer.
Any ideas on how to make this work?
EDIT: I understand that the ScrollViewer is a Decorator and that the content is not aware of the ScrollViewer. This separation is good and I don't want the content to be aware of the ScrollViewer. What I try to do is a purely visual (layout) thing. Simply show the ScrollViewer on top of the content.The behavior of the ScrollViewer should remain unchanged.
I think I now understand what you mean by "on top" - one way to do it is to use a control template that makes the ScrollContentPresenter span two rows and columns of a grid while the ScrollBars are in the 2nd rows and columns. The ScrollBars are set to be semi-transparent. The content will now draw under the scrollbars!
The Style I tried that works is as follows:
<Style x:Key="SVStyle" TargetType="{x:Type ScrollViewer}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter Grid.ColumnSpan="2" Grid.RowSpan="2"/>
<ScrollBar Name="PART_VerticalScrollBar"
HorizontalAlignment="Right"
Opacity="0.5"
Grid.Column="1"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar Name="PART_HorizontalScrollBar"
VerticalAlignment="Bottom"
Orientation="Horizontal"
Opacity="0.5"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Example usage:
<ScrollViewer HorizontalScrollBarVisibility="Auto" Style="{StaticResource SVStyle}" >
<StackPanel>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >World World</Button>
<Button Height="100" Width="800" >Hello World</Button>
<Button Height="100" Width="800" >Hello World</Button>
</StackPanel>
</ScrollViewer>
The result is along the lines of this:
It would be simple modify this so that the ScrollBars are initially very transparent (say, Opacity = 0.2) and have them become more opaque when the mouse enters the ScrollBar. That would be a nice effect and would keep the ScrollBars out the way until they're needed.
EDIT:
I've written this up on my blog for those who would like a little more detail.
I'm not sure if you wish to place the scrollbar of the scrollviewer on top of the content - if so answer 1, if you want the whole scrollViewer ontop of the content see answer 2.
1) You can change the visual representation of anything in WPF by applying a template. The trick in this case is to find what the existing representation of the ScrollViewer is, and then essentially re-implement all the same visuals just changeing the position of the ScrollBar as required. There are a couple of ways of finding all the visuals for a control - the easiest is from the WPF MSDN Samples - and nicely enough the ScrollViewer example provided by Microsoft shows how to change the position of the scrollbar.
BTW Microsoft tend to load their examples with lots of extra Xaml that you don't really need - play (ruthlessly cut out code) with the template until it does just what you want and no more.
2) My approach to placing the scroll view ontop of the content, would be to use two scrollviewers placed on top of each other. The 'top' is small, translucent (opacity = 50) and handles scrolling, the bottom is larger and has the document. Wire the scroll event from the top ScrollViewer so that it will also scroll the bottom one.
The idea is that the ScrollViewer is a decorator for the thing that it scrolls and clips. The thing being scrolled is completely unaware of the scrolling. This is simple and elegant - why is it not sufficient in your case?
Having said that, if the ScrollViewer does not do what you want, I suggest that you create ScrollBar controls and handle the events generated by it, moving the content that you wish to scroll in the event handlers. You may even be able to do some fancy data binding to avoid writing event handlers. I'm not sure how you are going to clip the content correctly, but that's a new can of worms.
If you need to layout one control on top of another, use a canvas control.

Window sizing related to contents

I've got two sizing issue regarding a Window I've got. The basic layout is like this
<Window MaxHeight="{DynamicResource {x:Static SystemParameters.VirtualScreenHeight}}"
MaxWidth="{DynamicResource {x:Static SystemParameters.VirtualScreenWidth}}"
>
<StackPanel>
<DockPanel LastChildFill="False">
<StackPanel DockPanel.Dock="Left"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
</DockPanel>
<ScrollViewer>
<WrapPanel x:Name="Container">
</WrapPanel>
</ScrollViewer>
</StackPanel>
</Window>
1) How do I made the Window not get smaller horizontally than the DockPanel's width?
2) How do I make the ScrollViewer be restricted to the limits of the Window? It is sizing itself to its contents, extending past the bounds of the Window.
It sort of used to work when I had
<Window><ScrollViewer/></Window>
, but I really don't want the DockPanel inside the scroller. In the current form, it is even forcing the Window to break its MaxHeight.
I would recommend you to use Grid with * Lenght instead of DockPanel and StackPanel.
Just get rid of those StackPanels. Replace them with Grids and you should be good. The layout logic of the StackPanel is such that it will give children as much room in a certain direction (perpendicular to the StackPanels orientation) as they ask for. That's why you're seeing the odd layout issues.

Resources