Navigation in a Silverlight application - c#

I recently got myself into Silverlight and I'm trying to develop an application where it reads data from XML.
My problem is that I have never understood how to actually navigate/make views visible/hidden/collapsed depending on what button the client is clicking. In example, this project reads the menu structure from a XML file and I'm using an ItemsControl to display the menuitems like this:
<ItemsControl ItemsSource="{Binding MenuItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Width="900" Height="40"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Tag="{Binding Url}" Content="{Binding Name}" Click="Button_Click"></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This code is in my MenuView.xaml (I'm using MVVM by the way) and on my MainPage.xaml I've included the MenuView like this:
<views:MenuView x:Name="menu" />
Now, when a user click one of the buttons, I need to show the correct view on my mainpage. The tricky thing (for me at least) is, that the content from the XML file is "of-type", so basically I have these views:
TextPageView
NewsPageView
Where the NewsPageView's layout is different than the TextPageView, which is just a regular textpage really.
How exactly should I be navigating/hiding/showing these views without using the navigation framework? :-)
Hope my question is clear, if not - please let me know and I will try to elaborate!
Thanks in advance.
All the best,
Bo

The Navigation Framework is your friend :)

Related

ContentControl inside ListBox going outside ListBox when scrolled

I currently have a ListBox that has a DataTemplate (for a custom class) that is a TabControl (bound to a list of charts) that contains a ContentControl (to show the chart).
When I scroll the ListBox, the tabs of the TabControl goes off the screen correctly. However the chart of the ContentControl within the TabControl goes out of the ListBox and over other elements.
Code Sample:
<ListBox x:Name="ListBox" ItemsSource="{Binding ChartItemsList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.Resources>
<DataTemplate DataType="{x:Type m:ChartItemsWrapper}">
<StackPanel Orientation="Horizontal">
<shared:PixelSnapper>
<TabControl Background="White" BorderBrush="DarkGray" ItemsSource="{Binding Items}" Margin="3,0" Padding="0" TabStripPlacement="Right">
<TabControl.ContentTemplate>
<DataTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="DarkGray" BorderThickness="0,1,0,0">
<Grid Background="White">
<Stuff>
<Grid Margin="0,25,0,0">
<ContentControl Content="{Binding Chart}" Visibility="Collapsed" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" x:Name="mainChart"/>
</Grid>
</Grid>
</Border>
</DockPanel>
<DataTemplate.Triggers ... />
</DataTemplate>
</TabControl.ContentTemplate>
<TabControl.ItemTemplate ... />
<TabControl.ItemContainerStyle ... />
</TabControl>
</shared:PixelSnapper>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel FlowDirection="LeftToRight" IsItemsHost="True" Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
I tried setting ZIndexes, changing the binding, but it just seems that ListBoxes and ContentControls don't mix. Any help would be appreciated.
Add HorizontalContentAlignment="Stretch" to your ListBox.
I had similar issue before and this fixed my issue.
Other than HorizontalContentAlignment="Stretch" suggested by vishakh369, you can also try ClipToBounds="True". Not sure what are the differences though, maybe you can try it out to see which one does it better.
Sorry this is not going to be the answer most people in the future will find useful but in my particular case the binding of <ContentControl Content="{Binding Chart}" .../> was pointing to a chart that can only be displayed within a WinFormHost.
Since WinForms and WPF are different rendering technologies, and WinForms UI elements will always be overlaid over WPF ones which is causing my WinForm charts to go outside the ListBox when they were supposed to be scrolled "off screen."
For more on this, refer to this stackoverflow question or this MSDN post. A note, in my research, some people were saying this problem was fixed in the .NET 4.5 release but it seems that it was not due to complications and had to be dropped from the release (see link).

Printing custom usercontrols with MVVM WPF

I have a view where I display a bunch of trading cards. Each card is a user control, and these are all displayed in a window. There are 4 cards to a row for however many rows are in some observable collection of cards. I want to be able to print this. I have done this in the past by recreating all the UI elements in the code-behind, but I want to rewrite this using MVVM, and even though I could still do this method in MVVM, it doesn't seem to be the cleanest solution. Does anyone know a simpler way to achieve this? Here is my XAML code for the Window of what I want to print:
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding StateManager.Cards}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type cardModels:AttackCard}">
<StackPanel>
<cardViews:AttackCardControl />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type cardModels:EquipmentCard}">
<StackPanel>
<cardViews:EquipmentCardControl />
</StackPanel>
</DataTemplate>
...
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="960"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
As you can see, I have an ItemsControl that contains all the cards within a wrap panel with a fixed Width. The width of each Card is exactly 240, so this allows exactly 4 cards to fit per row. The Data Templates are for the displaying the different types of cards that all inherit from a Card class and are in an ObservableCollection. Any one have any ideas on how to print this? From my past program, I have also learned that only 2 rows will fit on a sheet of paper and it must be printed at a 90 degree angle (landscape view). Thank you for any help!

Reporting Services Prompt Area Functionality

I have a user control which is driven by data from a sql database. Each user control contains a query, which can be altered at runtime with parameters. I would like to replicate the functionality of the reporting services viewer, which has the prompt area as seen in the image below.
The example shown is made up of a single label and textbox. I am currently working towards an implementation like this. However it would be beneficial to be able to provide the users with a list of valid values, to ensure valid data is returned. It would also be nice to have dependencies between controls.
Does anyone know of an examples/implementations of something similar to this? Or any resources which could help with a solution?
Just for reference for others. I managed to implement this functionality using a list of a custom class along with a items collection.
Shown below is the Xaml. You can see the ItemsSource is bound to a list of my parameter class, and the item template binds a label/textbox to properties for each parameter.
<Grid Background="Silver">
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding Path=Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Prompt}" Grid.Column="0" TextAlignment="Right"/>
<TextBox Text="{Binding Path=Value}" Width="200" Grid.Column="1"/>
</Grid>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This is the output, for now it is as simple as labels and textboxes. I will come back to this and improve to use combos with limited values.

GUI for single interface approach

I've made a small application using MDI but I want to make another one where there is only one main window and the main container changes or updates. I'm sure this can be done without creating multiple panels but I've been doing a bit of reading and I can't seem to find how can I do this.
If I understand you correctly you want to keep only one form. You can use tab control and switch between different pages, or create a set of user controls and then manage yourself what user control to show
For my scrum information radiator (full screen application for a big TV in portrait) I decided to use a set of controls from Actipro. I have multiple windows, but only one visible at a time. The user can use the arrow keys to "swipe" windows in and out just like they're used to do in smartphones.
The control used was the ZapPanel, as seen in my xaml below:
<ListBox x:Name="listBox" Grid.RowSpan="2" BorderThickness="0" Focusable="False" SelectionMode="Single"
SnapsToDevicePixels="True" VerticalContentAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden" Background="Black">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<views:ZapPanel AreChildrenWrapped="True" Orientation="Horizontal" AreLeavingElementsAnimated="True" Background="Black" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<StackPanel Orientation="Horizontal" Height="30" Margin="10" VerticalAlignment="Top" Opacity="0.5" >
<Button Click="PrevButtonClick">Prev</Button>
<Button Click="NextButtonClick">Next</Button>
</StackPanel>
</Grid>

WPF Databinding stackpanel

Im a beginner in WPF programming, coming from .NET 2.0 C#.
Im trying to make a horizontal StackPanel which should be filled with data from a table in a database. The problem is that I want it to display an image with some text from the table below and then stack those two items horizontally.
Here's some pseudo-code to display what I want to do:
<StackPanel Orientation="horizontal" ItemsSource="{Binding Path=myTable}">
<StackPanel>
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}"></Label>
</StackPanel>
</StackPanel>
I simply cannot figure oout how to do this.
Julien's answer is correct for your written description, however, looking at your XAML, it appears you are looking for something like the following:
<DataTemplate x:Key="UserDataTemplate">
<StackPanel>
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}" />
</StackPanel>
</DataTemplate>
<ItemsControl x:Name="UserList" ItemTemplate="{StaticResource UserDataTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
You definately need an ItemsControl (or some derivation of) to bind your source to. Then you can change the the orientation by setting it's items panel (which I believe is a VirtualizingStackPanel with Vertical orientation by default) so just set it to a VirtualizingStackPanel with Horizontal Orientation. Then you can set the ItemsTemplate for each of your items to the layout you desire (an image stacked on top of text bound from your database).
Basically, you want to use a control capable of displaying an enumeration of objects. The control capable of this is the class ItemsControl and all of its descendants (Selector, ListBox, ListView, etc).
Bind the ItemsSource property of this control to a list of objects you want, here a list of users you've fetched from the database. Set the ItemTemplate of the control to a DataTemplate that will be used to display each item in the list.
Sample code:
In a Resources section (for example Window.Resources):
<DataTemplate x:Key="UserDataTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="User.png"/>
<Label HorizontalAlignment="Center" Content="{Binding Path=UserName}" />
</StackPanel>
</DataTemplate>
In your Window/Page/UserControl:
<ItemsControl x:Name="UserList" ItemTemplate="{StaticResource UserDataTemplate}" />
In your code behind:
UserList.ItemsSource = ... // here, an enumeration of your Users, fetched from your db

Categories