In SL4, I am finding it oddly difficult to figure out how to make a HyperlinkButton navigate to another Silverlight page in the same application when clicked. The structure is:
<HyperlinkButton Content="Technical Information Screen" Height="23"
Name="hyperlinkButton1" Width="320" NavigateUri="/tis.xaml" />
"tis.xaml" is in the same folder as MainPage.xaml, which is where this button is located. When clicked, the button raises "404 Not Found".
If I change to having the NavigateUri get filled programmatically in the MainPage constructor, as in:
hyperlinkButton1.NavigateUri = new Uri("/tis.xaml", UriKind.Relative);
I get the same result, as I do with not decorating with "/", and with UriKind set to Absolute or RelativeOrAbsolute. It is all very mysterious, but I know it must be do-able somehow, or why have the control at all?
Hyperlink button's default behavior is to point the browser to a different page (i.e. a whole other HTML page).
Navigation between XAML pages within the same application is explained in detail here (I suppose you will have to call NavigationService.Navigate() in the click event of the hyperlink button).
You need to set the HyperlinkButton's TargetName property to the Name of the navigation:Frame control which you want to fill in with the new page. Condensing it down to essentials:
<UserControl ...
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation">
<Grid>
<HyperlinkButton Content="Technical Information Screen" NavigateUri="/tis.xaml" TargetName="ContentFrame"/>
<navigation:Frame x:Name="ContentFrame"/>
</Grid>
</UserControl>
Most likely the issue is with the uri format, try pointing to the aspx page hosting the silverlight control.
hyperlinkButton1.NavigateUri = new Uri("http://foo.page.aspx");
Related
I am working on a UWP app and encountered an issue with the background image changing when I navigate to different pages.
In my RootPage.xaml file I have this layout
<Grid x:Name="Root">
<Grid.Background>
<ImageBrush
ImageSource="{Binding ImageSource}"
Stretch="UniformToFill" />
</Grid.Background>
<SplitView Name="Splitter" IsPaneOpen="False" DisplayMode="Overlay" PaneBackground="Transparent">
<SplitView.Pane>
<Grid>
<!-- list view -->
</Grid>
</SplitView.Pane>
<Frame Name="MainFrame"></Frame>
</SplitView>
</Grid>
In my code behind I handle changes in the selection changed event like so
private void SectionList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// code to get the navigation item page the event args
// then navigate like so
MainFrame.Navigate(item.DestinationPage);
}
But when I navigate to the one of the other pages my background image that was set on the grid is lost. It just turns black.
I am missing something here, I have been watching a ton of tutorials but must have missed something. I just want the page content where frame is, and replace that depending on where the user navigated to. But leave the split view navigation stuff to live on every page.
Once you navigate to your "DestinationPage" you will see whatever background is set on the root element of that page (default is: {ThemeResource ApplicationPageBackgroundThemeBrush} ).
If you want the page to be transparent, so that the user will see the background image of the root Grid, you can set Background="Transparent" on your page's root element.
Hope this helps - thanks!
Stefan Wick
I am building a WPF app using NavigationWindow with many Pages. I have created popups within a Page like follows:
XAML
<Popup PlacementTarget="{Binding ElementName=mainDisplay}" Placement="Center" Name="myPopup">
<Frame Name="popupFrame"/>
</Popup>
codebehind
popupFrame.Navigate(new MyUserControl()); //navigate to a user control
myPopup.IsOpen = true; //to "pop up" popup
Except now, I would like a "global" popup, which is based on a timer and can popup at any page when time is up. The timer is inside the main NavigationWindow's codebehind and keeps ticking across all pages, but I cannot place the popup directly within the NavigationWindow since it does not support direct content. How can i achieve this?
Thanks in advance!
As it turns out, it's very simple. I just need to create a popup in codebhind of NavigationWindow, and set myPopup.IsOpen=true when time is up.
I am currently writing a desktop application, but I cannot seem to get my head around what to use when redirecting someone to a new section of the application.
My options appear to be
Window
Page
UserControl
but I don't understand what the difference between them is, and when I should use each one.
Could someone explain the differences for me, and give an example of what situations/applications you may use each one for?
A Window object is just what it sounds like: its a new Window for your application. You should use it when you want to pop up an entirely new window. I don't often use more than one Window in WPF because I prefer to put dynamic content in my main Window that changes based on user action.
A Page is a page inside your Window. It is mostly used for web-based systems like an XBAP, where you have a single browser window and different pages can be hosted in that window. It can also be used in Navigation Applications like sellmeadog said.
A UserControl is a reusable user-created control that you can add to your UI the same way you would add any other control. Usually I create a UserControl when I want to build in some custom functionality (for example, a CalendarControl), or when I have a large amount of related XAML code, such as a View when using the MVVM design pattern.
When navigating between windows, you could simply create a new Window object and show it
var NewWindow = new MyWindow();
newWindow.Show();
but like I said at the beginning of this answer, I prefer not to manage multiple windows if possible.
My preferred method of navigation is to create some dynamic content area using a ContentControl, and populate that with a UserControl containing whatever the current view is.
<Window x:Class="MyNamespace.MainWindow" ...>
<DockPanel>
<ContentControl x:Name="ContentArea" />
</DockPanel>
</Window>
and in your navigate event you can simply set it using
ContentArea.Content = new MyUserControl();
But if you're working with WPF, I'd highly recommend the MVVM design pattern. I have a very basic example on my blog that illustrates how you'd navigate using MVVM, using this pattern:
<Window x:Class="SimpleMVVMExample.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SimpleMVVMExample"
Title="Simple MVVM Example" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:HomeViewModel}">
<local:HomeView /> <!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:ProductsViewModel}">
<local:ProductsView /> <!-- This is a UserControl -->
</DataTemplate>
</Window.Resources>
<DockPanel>
<!-- Navigation Buttons -->
<Border DockPanel.Dock="Left" BorderBrush="Black"
BorderThickness="0,0,1,0">
<ItemsControl ItemsSource="{Binding PageViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding }"
Margin="2,5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
<!-- Content Area -->
<ContentControl Content="{Binding CurrentPageViewModel}" />
</DockPanel>
</Window>
Window is like Windows.Forms.Form, so just a new window
Page is, according to online documentation:
Encapsulates a page of content that can be navigated to
and hosted by Windows Internet Explorer, NavigationWindow, and Frame.
So you basically use this if going you visualize some HTML content
UserControl is for cases when you want to create some reusable component (but not standalone one) to use it in multiple different Windows
All depends on the app you're trying to build. Use Windows if you're building a dialog based app. Use Pages if you're building a navigation based app. UserControls will be useful regardless of the direction you go as you can use them in both Windows and Pages.
A good place to start exploring is here: http://windowsclient.net/learn
We usually use One Main Window for the application and other windows can be used in situations like when you need popups because instead of using popup controls in XAML which are not visible we can use a Window that is visible at design time so that'll be easy to work with
on the other hand we use many pages to navigate from one screen to another like User management screen to Order Screen etc In the main Window we can use Frame control for navigation like below
XAML
<Frame Name="mainWinFrame" NavigationUIVisibility="Hidden" ButtonBase.Click="mainWinFrame_Click">
</Frame>
C#
private void mainWinFrame_Click(object sender, RoutedEventArgs e)
{
try
{
if (e.OriginalSource is Button)
{
Button btn = (Button)e.OriginalSource;
if ((btn.CommandParameter != null) && (btn.CommandParameter.Equals("Order")))
{
mainWinFrame.Navigate(OrderPage);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
That's one way of doing it We can also use a Tab Control instead of Fram and Add pages to it using a Dictionary while adding new page check if the control already exists then only navigate otherwise add and navigate. I hope that'll help someone
Most of all has posted correct answer. I would like to add few links, so that you can refer to them and have clear and better ideas about the same:
UserControl:
http://msdn.microsoft.com/en-IN/library/a6h7e207(v=vs.71).aspx
The difference between page and window with respect to WPF:
Page vs Window in WPF?
I have a treeview at the left side of the screen, and when I click on any of the TreeViewItem, I want the right side of the screen to change accordingly.
For example, clicking on 'Project' would display on the right half of the screen, a label for project name along with the project name in a text box, and a similar label-textbox pair for some other fields. Clicking on a sub-option of 'Project' such as 'Task 1' should change the right half of the screen such that instead of labels and textboxes for project name and details, it should now be for task name/details. Atm, I only care about label-textbox pairs but in the future I'll need some more sophisticated options, maybe buttons and tables.
What I thought of was to have a grid premade for each option, when I clicked on 'Project' there would be a grid which displays all the info for a Project. And when I then clicked on 'Task 1', the Project grid should be hidden and the Task grid should be displayed with the fields filled out.
Is this possible? What should I be using to create templates that I can then choose from?
Firoz already mentioned the important bit. A rough guess is that you're not using MVVM pattern, so to minimize the adaption effort, you could add a Content Control to your window and set the content of this control whenever a selection is made. You can put any User Control in there.
Using MVVM would mean you bind that Content Control to a property on your ViewModel (of type UIElement or UserControl) and set an instance whenever a bound selected values changes. Speaking of selected Value, I think the default TreeView is not really Binding-friendly, so you might end up with behaviours that do the binding for you.
What you are asking to do is quite easy and possible, but I don't think you are thinking quite big enough.
As your project grows and the number of different things that you want to show expands, then you are going to need to show and hide more and more controls. This is quite quickly going to get unmanageable. Instead think about some other controls deal with this, in some ways you are doing something very like a tabbed dialog, just with a hierarchical set of tabs.
A tabbed dialog has a panel and a set of tabs, when you click on each tab, the content of the panel changes. In fact you can create UserControls one for each specialised set of UI that you want to display, e.g. you could have a ProjectControl that displays all of your project textboxes, labels, buttons etc.
In addition WPF has this neat feature called DataTemplates, these define how a type of data should look when it is displayed. So if you where to have a
public class MyProject
{
public string Name {get;set;}
}
Then you could define
<DataTemplate DataType="{x:Type MyProject}>
<TextBox Text="{Binding Name}"/>
</DataTemplate>
And WPF will automatically convert the data into to its visual form if you set it as the content of the tab panel.
However this type of displaying content in a panel is not the only WPF control that does this. There is also something called a NavigationFrame, which also can be used wrapped into a Window as a NavigationWindow. This control provides you ways to navigate to the next Page to display. Pages can be just like the UserControls in a tabbed dialog, but can also be URIs, enabling you to link in content from the web if you wish. In addition you can call NavigateTo from other controls enabling you build much more usable interfaces.
I worked through the process of building a full windows control panel style interface in
http://alski.net/post/2012/01/11/WPF-Wizards.aspx
and http://alski.net/post/2012/01/13/WPF-Wizards-part-2-Glass.aspx
I've added later VS2012 style glows in
http://alski.net/post/2013/09/14/WPF-Re-creating-VS2012Office-2013-window-glow.aspx
And then released the entire source code as open source at
http://winchrome.codeplex.com/
This comes with support for embedding Navigation panels with
<WinChrome:SearchableNavigationWindow
x:Class="WinChrome.Win7Demo.MainWindow"
...
xmlns:WinChrome="clr-namespace:WinChrome;assembly=WinChrome"
Style="{StaticResource Win7NavigationWindow}">
<WinChrome:SearchableNavigationWindow.Navigation>
<view:Navigation x:Name="navigationTree"/>
</WinChrome:SearchableNavigationWindow.Navigation>
(Full source code)
Where the navigation window is embedded as, but can also be a TreeView.
<UserControl x:Class="WinChrome.View.Navigation" ...>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Padding="12,0"
VerticalScrollBarVisibility="Auto" >
<StackPanel>
<Button
Margin="0,12,0,0" Style="{StaticResource LinkNavigatorButtonStyle}"
Content="Home"
Command="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Win7Demo:MainWindow}, AncestorLevel=1},
Path=GoHomeCommand}" />
</StackPanel>
</ScrollViewer>
(Full source code)
I'm trying to make a window layout usable from different windows.
As you can see from image, I've got a logo, a left vertical progress bar and two control buttons in the bottom part of the window (plus menu bar and status bar).
Those parts should be always the same in different windows, and play/stop should be interacting run-time with the common parts but also with parts build in the middle of the window ("part in each window different").
I can't understand what i should use for creating a standard layout callable from each window where I need it, made in a way were I can replace for each of those windows just the middle part.
Any tips? I probably just need to understand the way to go (sad to be c# wpf newbie)!
You can use a content control and then just switch the content
Master page for regions
This link has what you need. You can put the page templates in a separate file if you will be doing lots of content switching
If you create a user control with a <ContentPresenter> where you want the variable content to be, you can inject your own controls into the user control.
The user control would look like:
<UserControl>
<Grid>
<!-- Header Stuff -->
<ContentPresenter Name="MyContentPresenter" />
<!-- Footer Stuff -->
</Grid>
</UserControl>
In your windows, you'd have:
<Window>
<Grid>
<MyUserControl>
<MyUserControl.Content>
<!-- your window specific code here -->
</MyUserControl.Content>
</MyUserControl>
</Grid>
</Window>
You will need to expose a property called Content on your user control that returns/sets the Content property of the ContentPresenter element on the user control.
In the code-behind of the user control:
public object Content
{
get { return MyContentPresenter.Content; }
set { MyContentPresenter.Content = value; }
}