I have a window with a FrameContent that I use to navigate between pages:
<Frame Name="FrameContent" VerticalAlignment="Stretch" Margin="0,34,-0.8,0.4" Grid.RowSpan="2"/>
It works great, but it only appears after I have already navigated to a page, where I would like to see it (even though back/forward will be greyed out) from the beginning.
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
FrameContent.Navigate(new HomeView());
}
I tried adding
ShowsNavigationUI="True"
Attribute to the HomeView page but it did nothing.
Does anyone know if this is possible?
Try adding NavigationUIVisibility="Visible", let me know if it works.
Related
I have what should be a very simple desktop application I'm working on but I'm having issues doing a few basic tasks. I'm using Visual Studio 2013.
I have created a project from a blank WPF template. I created a new Page, named Page1.xaml, to go along with the default MainWindow.xaml Window.
In my MainWindow.xaml window I have Grid and inside the grid is an Image.
<Grid MouseDown="Grid_MouseDown_1" Cursor="Hand" >
<Image Name="ImageIntro" Source="images/Stories-intro.jpg" Stretch="None" />
</Grid>
The Grid has a MouseDown event so that I can detect when a user clicks anywhere inside the Grid.
private void Grid_MouseDown_1(object sender, MouseButtonEventArgs e)
{
}
Pretty basic and that all works and compiles as intended.
The issue I have is that I'm unable to load the Page1.xaml inside my window on MainWindow.xaml. I don't want to open a separate window, I just want the content on Page1.xaml to be displayed inside the visible window of MainWindow.xaml.
I tried using the following but I get an error when I click the on my link: An unhandled exception of type 'System.NullReferenceException' occurred
private void Grid_MouseDown_1(object sender, MouseButtonEventArgs e)
{
Uri uri = new Uri("Page1.xaml", UriKind.Relative);
NavigationService ns = NavigationService.GetNavigationService(this);
ns.Navigate(uri);
}
This is not a browser application, it's simply a desktop application. The first screen (MainWindow.xaml) should just click thru to display the second screen (Page1.xaml).
I want the Page1.xaml content to take up the entire Window of MainWindow.xaml (sorry, but I can't stress that enough, I don't want a frame or any content from MainWindow.xaml showing when the user is on Page1.xaml).
I'm pretty new to Desktop apps but I have extensive knowledge with .Net C# for web applications. I'm not against changing the flow of what I have if there's a better way to accomplish this. For example, perhaps I shouldn't be using a Window to Page navigation and should instead use a Window to Window or something else.
I would imagine this would be a relatively simple task, but I haven't found anything that works yet so hopefully someone on here can explain it.
create a frame in Main Window
then in your event hander
Page1 mypage=new Page1();//object of the page 1
frame.Navigate(mypage);//pass it to frame navigate method
Read this MSDN link, the requirements for that to work say that this (in your code) must be a Frame. I don't see any XAML code here, but I'm guessing this is a Window. You need a frame to host the navigation, so your MainWindow should probably just the frame, and the contents of your current window should be "Page0".
Thanks Everyone who helped, here is the solution I used (I wanted to make sure a code example was here for anyone who has this same issue in the future).
I added a Frame to my MainWindow.xaml page:
<Grid MouseDown="Grid_MouseDown_1" Cursor="Hand" >
<Image Name="ImageIntro" Source="images/Stories-intro.jpg" Stretch="None" />
<Frame Name="Frame1" Content="" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
Then I added the following to my event:
private void Grid_MouseDown_1(object sender, MouseButtonEventArgs e)
{
Page1 mypage = new Page1();
Frame1.Navigate(mypage);
}
This allowed me to click on my link and the new page, Page1.xaml appeared. There was also a navigation bar that appeared at the top and the content didn't completely take up the MainWindow.xaml window but I think I can fiddle around with the settings and get it to where I want it.
Much thanks to Filippo B, Nauman Ahmad, and CodingGorilla for the assist.
I'm having a rather frustrating problem here... I have a WPF Page that contains a TabControl, and the content of the various TabItems is another WPF Page (hosted in a Frame because Page can only have Frame or Window as a parent). Even though the FlowCalibrationSummaryView is being displayed, everything on it is empty because the data binding of the SummaryViewModel is not working for some reason. Here's part of the XAML:
<TabControl Grid.Row="0">
<TabItem Header="Current Calibration">
<TabItem.Content>
<Frame>
<Frame.Content>
<view:FlowCalibrationSummaryView DataContext="{Binding SummaryViewModel}"/>
</Frame.Content>
</Frame>
</TabItem.Content>
</TabItem>
</TabControl>
I have a break point on the get of SummaryViewModel, and it is only getting hit by the code that is constructing it in the parent view model. Here's the property being bound to:
public const string SummaryViewModelPropertyName = "SummaryViewModel";
private FlowCalibrationSummaryViewModel _SummaryViewModel;
public FlowCalibrationSummaryViewModel SummaryViewModel
{
get { return _SummaryViewModel; }
set
{
if (_SummaryViewModel == value)
return;
_SummaryViewModel = value;
RaisePropertyChanged(SummaryViewModelPropertyName);
}
}
At this point I'm completely stumped, I cannot for the life of me figure out why this binding is not working. Any help would be much appreciated.
Update: It definitely has something to do with it being in a Frame. I tried changing the FlowCalibrationSummaryView to a UserControl instead of a Page to see if that helped, and it didn't, then I tried taking it out of the Frame it was wrapped in and that worked. All of the views in my project are done as Pages so for consistency's sake I'd prefer this to be a Page, but then I have to host it in a Frame. Is there something I'm missing here, or is the proper usage to do it as a UserControl?
I would take a look at the answer provided in this question. It seems to provide a specific explanation of the behavior of Frame in this case.
Unless there is a specific reason you have chosen Frame over UserControl, you would be better off re-implementing this (and any other sub-view) as UserControl instead.
I have a problem with a ContentControl in Silverlight. The ContentControl displays its region only the first time I access to the view. The others times, it displays anything unless I refresh the page.
Here is the xaml code
<Grid x:Name="LayoutRoot">
<ContentControl HorizontalAlignment="Center"
VerticalAlignment="Top" Name="contentControl" />
</Grid>
and the code behind :
public Staff()
{
InitializeComponent();
this.Title = ApplicationStrings.StaffPageTitle;
IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
if (!regionManager.Regions.ContainsRegionWithName(_moduleName))
{
RegionManager.SetRegionManager(contentControl, regionManager);
RegionManager.SetRegionName(contentControl, _moduleName);
}
}
If I try to set the region each time, an error is thrown saying that the module already exists.
What should I do, to display the module each time I access to the view?
Thanks :)
Check this out. (start reading from ADAPTING TO THE REGION). Inside is a reference to John Papa's blog. Check that out as well.
Hope it helps you out.
So I have a Panorama control and the PanoramaItems are programmatically added to the control using the following template.
<UserControl>
<Grid x:Name="LayoutRoot">
<controls:PanoramaItem Name="sitePanoramaItem" Header="{Binding Name}">
<Controls:DockPanel VerticalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Controls:DockPanel.Dock="Top">
<Image Source="../Images/action.png" Width="64" />
<TextBlock Text="{Binding Stats, Mode=TwoWay}" FontSize="45" Margin="15,0,0,0" />
</StackPanel>
<Grid x:Name="graphCanvas" HorizontalAlignment="Stretch" Margin="10,10,10,10"> </Grid>
</Controls:DockPanel>
</controls:PanoramaItem>
</Grid>
</UserControl>
When I click on graphCanvas what I'd like to do is sorta pop the graphCanvas out and display that fullscreen then when I click again restore it to where it was. I've been all over this site and Google and can't find anything similar to what I'm looking for.
I would still like to maintain the Panorama control functionality so that the graphCanvas is still the only one visible but you can cycle through them. Currently I have it sorta working in that I remove the Grid from the DockPanel and put it directly in the LayoutRoot while making the sitePanoramaItem collapsed. However, it's not fullscreen as the Panorama name is still visible (I guess I could hide that as well...) When I put the graphCanvas back int he DockPanel the size of the canvas is all screwed up.
I was hoping there was a simpler way.
Is it even possible?
It is possible to create the UI you describe but it's not going to be simple. You're on the right track with removing it in code and adding it the LayoutRoot and making the Panorama hidden. However you would have to code the scrolling behavior yourself and that is going to be quite tricky - especially making it feel the way to panorama does.
One trick you could try is actually layer a PivotControl on top of your Panorama and have it be collapsed by default. Also edit it's template to remove all default content eg: remove the header control, set margins to 0, etc). Then when you want to go full screen you can remove all the graphCanvases from the Panorama items and and add them to new PivotItems in the PivotControl. Then hide the Panorama and show the Pivot. This will give you scrolling capability for free and the illusion of full screen.
Having said all that I'm not sure I would recommend this. The more common approach would be to simply be to navigate to another page when the user selects an item and handle the full screen aspects there (possibly using the Pivot control again for scrolling). And when you want to leave "fullscreen" mode simply navigate back to the first page. Handling Tombstoning of the fullscreen state will be much easier with this approach for one thing.
You can try making the graphCanvas a Page and putting it in a different XAML. Then add a frame (name it InnerFrame for example) in the same place where you have the graphCanvas right now and navigate to that page with InnerFrame. When the frame is clicked, you navigate with the RootFrame of the app to your graphCanvas page. When you decide to close it, just navigate back with the RootFrame.
Hope it's clear enough :)
Edit:
Navigation in WP7 works very similar as the standard navigation in Silverlight 4, but it's a bit more restrictive. Just throw a PhoneApplicationFrame in your XAML like this:
<phone:PhoneApplicationFrame x:Name="Frame" />
This is basically the same as a Silverlight frame. All the pages you create inherit from PhoneApplicationPage by default, so they can be showed in a frame without any changes.
Your whole application actually runs on a PhoneApplicationFrame. If you take a look at your App class you will see this:
public PhoneApplicationFrame RootFrame { get; private set; }
Here's the MSDN documentation for the navigation system on WP7
I've been pounding away at this issue for a little while, and have only found part of the solution.
I'm trying to set up a TabControl so that I can in some cases prevent the user from changing the currently selected tab. When the user is prevented from changing the currently selected tab, then they are shown a dialog box.
I have already read the following documents:
WPF - reset ListBox scroll position when ItemsSource changes
http://wizardsofsmart.net/uncategorized/itemssourcechanged-event-using-attached-dependency-properties/
http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/
http://social.expression.microsoft.com/Forums/en-US/wpf/thread/f7b46018-1e97-4bbe-ada8-49b75dbc1da2/
I have implemented the solution indicated in the 3rd link (though all of the above create the same error seen below). And it works, but...
Things mess up thoroughly if the user does the following:
attempts to change the tab when such an action is disallowed. The MessageBox pops up with the error.
the user clicks "OK" and is returned to the original window.
the user tries again to change the tab. No MessageBox appears.
if the user minimizes the window, and then maximizes it again, then the MessageBox that was supposed to appear earlier appears.
the user clicks "OK" and is returned to the original window... but the tab has been changed to the one they selected before, even though they should not be able to change tabs.
This is obviously not ideal behavior. Why isn't the MessageBox appearing the second time, and why is the tab changing when it should be disallowed from doing so?
If I remove the MessageBox part, it works fine.
Here is the code for the TabControl.SelectionChanged event handler:
bool _isChanging = false;
private void tabControlForNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isChanging && canChangeTabs.IsChecked.HasValue)
{
_isChanging = true;
bool canLeave = canChangeTabs.IsChecked.Value; //normally this would be replaced by a check in the ViewModel
if (!canLeave)
{
int prevIndex = tabControlForNavigation.Items.IndexOf(tabControlForNavigation.SelectedContent);
tabControlForNavigation.SelectedIndex = prevIndex;
MessageBox.Show("Can't change tabs!"); //if I comment out this line, everything works fine.
}
_isChanging = false;
}
}
I am using MVVM to implement this. The Window looks like this:
<Window x:Class="TestTabControlSwitching.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="canChangeTabs"
Content="Can Change Tabs"
IsChecked="True" />
<TabControl x:Name="tabControlForNavigation"
Grid.Row="1"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Collection}"
SelectedItem="{Binding SelectedItem}"
SelectionChanged="tabControlForNavigation_SelectionChanged"
Margin="4"
HorizontalAlignment="Stretch">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</Grid>
I'm omitting the rest of the code for sake of brevity- there is a pretty straight-forward ViewModel structure backing the window.
As you noticed, the problem is the MessageBox inside the event handler. The focus will change to the MessageBox and you can get all kind of undesired effects. I've had my own problems with this.
Here is a couple of SO question on the same subject
WPF: Does MessageBox Break PreviewMouseDown?
Wpf stop routing event when MessageBox appear?
If you must display a message to the user then an alternate approach might be to create a new Window which you style like a MessageBox and then call Show (not ShowDialog) on it inside the event handler.
I know this post is a bit old, but I have a very easy way to accomplish this:
Use the tab_Enter event and create a method that performs your check and displays a MessageBox to the user and then set myTabs.SelectedIndex to the prior index. A simple example:
private void someTab_Enter(object sender, EventArgs e)
{
if (myCondition)
{
MessageBox.Show("Sorry, myCondition will not let you move to this tab.");
myTabs.SelectedIndex = someOtherTabIndex;
}
}
This was a very detailed question. I had the same problem you had (i.e. the message box doesn't display on 2nd or 3rd selection changed until you minimize and maximize the window) and after much debugging and multiple google searches, stumbled on the below linked MSDN forum post.
[TabControl SelectionChanged Strange Behaviour?]
Please ignore the poorly formatted question and answer. But as mentioned in the answer, putting it inside a dispatcher and focussing the selected tab after setting the index resolved the issue for me.
You are missing an easy trick. Just make focusable=False for the Tab header.
<TabItem Header="MY TAB" Focusable="False">
You could bind this property to your view model.
<TabItem Header="MY TAB" Focusable="{Binding Bool_CanHasCheeseBurger}">