Implement Semantic Zoom without listview, Gridview? - c#

I am trying to implement Semantic Zoom control but not with listview, Gridview or grouping. My UI has following XAML
ZoomIn
<!--Your ZoomIn view here-->
<ScrollViewer>
<StackPanel>
<Grid x:Name="Item1" />
<Grid x:Name="Item2" />
<Grid x:Name="Item3" />
<Grid x:Name="Item4" />
<Grid x:Name="Item5" />
</StackPanel>
</ScrollViewer>
ZoomOut
<!--Your ZoomOut view here-->
<ScrollViewer>
<StackPanel>
<Image x:Name="ImageItem1" />
<Image x:Name="ImageItem2" />
<Image x:Name="ImageItem3" />
<Image x:Name="ImageItem4" />
<Image x:Name="ImageItem5" />
</StackPanel>
</ScrollViewer>
On clicking on an image in Zoomout it should take to the corresponding to Grid in Zoomin view.
How can i achieve this? Till now I have implemented Semantic zoom using listview, gridview and grouping.

It's sloppy to use a control like SemanticZoom for controls it is not intended to use.
Having said that, you can do this:
<SemanticZoom>
<SemanticZoom.ZoomedInView>
<GridView>
<GridView.Header>
<StackPanel>
<TextBlock>One</TextBlock>
<TextBlock>Two</TextBlock>
<TextBlock>Three</TextBlock>
</StackPanel>
</GridView.Header>
</GridView>
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<GridView>
<GridView.Header>
<StackPanel>
<TextBlock>Four</TextBlock>
<TextBlock>Five</TextBlock>
<TextBlock>Six</TextBlock>
</StackPanel>
</GridView.Header>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
Best of luck!

Related

Resizable window with ScrollViewer

I have a wpf c# application.
In my window I want to start with a certain height when it opens. But I also want to allow the user to be able to resize the window.
My window has a dockpanel with lastChildFill set to true. It has on the left a tree to pick a section you would like to see it's details, in the middle a seperator and on the right the section's details (you need last child fill so that this will get all the space left).
The code looks like this:
<StackPanel>
<DockPanel LastChildFill="True" Background="#344755">
<TextBlock Text="Header" Background="#344755" Foreground="White"/>
</DockPanel>
<DockPanel LastChildFill="True" Margin="5">
<telerik:RadTreeView x:Name="treeV">
<telerik:RadTreeView.Items>
<telerik:RadTreeViewItem Header="General" />
<telerik:RadTreeViewItem Header="General2" />
<telerik:RadTreeViewItem Header="General3" />
<telerik:RadTreeViewItem Header="General4" />
</telerik:RadTreeView.Items>
</telerik:RadTreeView>
<Separator/>
<Grid >
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl>
<DockPanel LastChildFill="True" Margin="5">
<Grid >
<TextBlock Text="Something"></TextBlock>
<CheckBox HorizontalAlignment="Right"/>
</Grid>
</DockPanel>
// And many more dock panels
</ItemsControl>
</ScrollViewer>
</Grid >
</DockPanel>
</StackPanel>
This is my problem: If I don't give the second dock panel height than the window automatically grows bigger and the scroll never shows. If I do give height, then the scroll does show but if the user resizes the window the dock panel doesn't resize and so doesn't the seperator.
Any ideas?
You need to Rethink your layout
for one thing you don't need to have a dock panel to fill the available area
here is a quick description of the most common layouts
StackPanel Creates a List of items in a top down or left to right
arrangement
Grid Attaches item to a grid define by sized rows and columns (uniform grid does the same but with rows and colums set to equally fill the available space)
Dockpanel attaches items to its edges using the order they are added
and the Dock property, with by default the last item set to fill the
middle
Canvas position items at fixed distances from the edges
So given controls w,x,y,z if you want w to be on the left z on the right and x & Y to share the centre
<DockPanel>
<w DockPanel.Dock="Left" />
<z DockPanel.Dock="Right" />
<UniformGrid Columns="2">
<x/>
<y/>
</UniformGrid>
</DockPanel>
if you wanted w to cover the first 1/4 of the screen and x,y & z to be stacked vertically on the remaining 3/4 and scrollable you would do
<Grid>
<Grid.ColumnDefintions>
<ColumnDefintion \>
<ColumnDefintion Width="3*" \>
<Grid.ColumnDefintions>
<w/>
<ScrollViewer>
<StackPanel>
<x/>
<x/>
<x/>
</StackPanel>
</ScrollViewer>
</Grid>
if you only have 1 item inside a layout container then that container is not required
A quick fiddle with you above code and it simplfies to
<DockPanel Background="#344755">
<TextBlock DockPanel.Dock="Top" Text="Header" Foreground="White"/>
<TreeView x:Name="treeV">
<TreeViewItem Header="General" />
<TreeViewItem Header="General2" />
<TreeViewItem Header="General3" />
<TreeViewItem Header="General4" />
</TreeView>
<Separator/>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
or if you really don't have a collection to bind the items control to
<DockPanel Background="#344755">
<TextBlock DockPanel.Dock="Top" Text="Header" Foreground="White"/>
<TreeView x:Name="treeV">
<TreeViewItem Header="General" />
<TreeViewItem Header="General2" />
<TreeViewItem Header="General3" />
<TreeViewItem Header="General4" />
</TreeView>
<Separator/>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
<CheckBox HorizontalAlignment="Right">Something</CheckBox>
...
</StackPanel>
</ScrollViewer>
</DockPanel>

ScrollView not working in Windows 10

I have a ViewModel with about 200 contacts and I am binding it to a ListView
<Grid>
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ListView x:Name="ContactListing" ItemsSource="{Binding ContactListing}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=DisplayName}" />
<Image Source="{Binding Thumbnail,Converter={StaticResource ResourceKey=contactConv}}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</Grid>
Would be great if someone could explain the details behind the ScrollViewers visibility
A ListView control already contains a ScrollViewer and implements scrolling based on the amount of items, there is no need to wrap this control in another ScrollViewer. You can double check this in the default ControlTemplate of ListView at line 6219 in the generic.xaml file containing all Windows 10 styles:
C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10240.0\Generic\generic.xaml
So you simply have to remove the ScrollViewer from your XAML fragment.
<Grid>
<ListView x:Name="ContactListing" ItemsSource="{Binding ContactListing}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=DisplayName}" />
<Image Source="{Binding Thumbnail,Converter={StaticResource ResourceKey=contactConv}}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Note: As you're using a ListView, I suppose you want all your items stacked above each other. If you want multiple columns to show your items, use a GridView instead.

WPF Tab Control force Scrollviewer to display newly added item

I am using WPF MVVM with C#. I have a Scrollviewer in a UserControl and I need the following functionality that I haven't been able to work out how to do which is basically:
When an Item gets added to the content of my ScrollViewer; if the item added is not visible I would like my ScrollViewer to scroll down so that I can view my newly added Item in my ListView. I have been able to bind the selected item successfully but not sure how to make it scroll to it.
That's all there really is to it but I'm not sure how to do this. If there's any comments or questions I'll try to suitably amend the post, I've included the .xaml below
Thanks
<ScrollViewer Background="Pink" HorizontalAlignment="Left" Height="173" x:Name="ScrollViewer1" Width="560" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
<Grid Name="GridValuesAndpartss" VerticalAlignment="Top" Height="165">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="370" />
<ColumnDefinition Width="204" />
</Grid.ColumnDefinitions>
<ListView SelectedItem="{Binding SelectedBetmyValue, Mode=TwoWay}" ItemsSource="{Binding Values}" Name="BetValuesListView" Height="Auto" Margin="0,0,0,0" myValueMode="Single" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridViewColumn Header="Price " Width="95">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="-7,0,0,0" MinWidth="95" Width="Auto">
<TextBlock Text="{Binding Path=PriceTypeCode}" Foreground="Black" FontSize="10" ToolTip="Price Type Code" />
<TextBlock Text=":" Foreground="Black" FontSize="10" ToolTip="Price Type Code" />
<TextBlock Text="{Binding Path=PriceTaken,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Red" FontSize="10" ToolTip="Price Taken" />
<TextBlock Text="." FontSize="4" />
<TextBlock Text="{Binding Path=PriceCurrent,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Black" FontSize="10" ToolTip="Price # Scan Time" />
<TextBlock Text="." FontSize="4" />
<TextBlock Text="{Binding Path=PriceSP,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Green" FontSize="10" ToolTip="Price SP" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</ScrollViewer>
I would try to use here the code behind a little bit.
Give the ScrollViewer a name (like 'x:Name="MyScrolly"').
Listen to the 'SelectionChanged'-Event of ListView.
In the event handler of selection changed event (code behind) call:
MyScrolly.ScrollToBottom();
I think the new item is always at the bottom. If not try this method: 'ScrollToVerticalOffset()'.

multiple stackpanels in ScrollViewer Windows 8 XAML

I seem to be having a problem with adding multiple StackPanels in a ScrollViewer. I can add the first one and it displays the data I want but when I try to add the second StackPanel is fails and brings the error "Duplication assignment to the 'Content' property of the 'ScrollViewer' object"
My front end code is like below:
<ScrollViewer VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
ZoomMode="Disabled"
Grid.Column="1"
Grid.Row="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<StackPanel Style='{StaticResource BlueFirstStackPanel}'>
<TextBlock Text='Facility Patient Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient Support Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='NHIF Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient National ID:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
</StackPanel>
</ScrollViewer>
My C# code for the code has this in it:
public sealed class ScrollViewer : ContentControl
{
}
And the above displays very well but when I add a second StackPanel it brings an error. Any help with this?
The ScrollViewer can only have one child control. Try wrapping both StackPanels in a Grid or another StackPanel:
<ScrollViewer>
<StackPanel x:Name="ScrollViewerChild">
<StackPanel x:Name="StackPanel1">
</StackPanel>
<StackPanel x:Name="StackPanel2">
</StackPanel>
</StackPanel>
</ScrollViewer>

Different Object-Types in Grid- or ListView

I'm currently trying to figure out how to show different types of objects in a GridView, look at this Pic for example:
the last element on the right side is different than the other elements, so if i bind an observablecollection to the GridView, how can i say that the last element is shown up in anohter layout.
currently I'm using this XAML-Code
<GridView x:Name="startView" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2" SelectionMode="None" Width="Auto">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
and this Code in the Back:
ObservableCollection<Movie> recentlyStarted = await Api.RecentlyStarted(3);
startView.DataContext = recentlyStarted;
but I have currently no clue how to let the last element show up in a different style
The easy way would be to have the two types of object as different classes (e.g. MoviePicStyle + MoviePlainStyle. Then move your DataTemplate out of the GridView, so that each object is picked up by type,
e.g.
<Window.Resources>
<DataTemplate DataType="{x:Type ViewModel:MoviePicStyle}">
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
<DataTemplate DataType="{x:Type ViewModel:MoviePlainStyle}">
...Different View...
</DataTemplate>
</Window.Resources>
<GridView...
Use template selector property of gridview and depending upon the type of object select the template. I did the same in my project. you need to write your own DataTemplateSelector.
I referred below link
http://babaandthepigman.wordpress.com/2012/02/08/datatemplateselector-winrt/

Categories