UWP App - background image is getting lost on navigate - c#

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

Related

Pointer events not triggered on UI Elements in custom control

I am creating an application with a UserControl containing multiple UI Elements. The UserControl is rendered into a StackPanel using ItemsControl since the number of UserControls to be rendered depends on user's input.
The basic XAML in the UserControl is as follows.
<Grid x:Name="Viewport" VerticalAlignment="Top" HorizontalAlignment="Center">
<Border x:Name="ViewportBorder" Background="White" BorderThickness="2, 2, 2, 2" BorderBrush="#FF353334" />
<Image x:Name="Image" Margin="0" UseLayoutRounding="True" ManipulationMode="Scale"/>
<InkCanvas x:Name="InkCanvas" />
<Canvas x:Name="SelectionCanvas" CompositeMode="SourceOver" />
</Grid>
I want to change the cursor icon when user is hovering over the SelectionCanvas (based on a condition check in my case as you might see in the source). It seemed pretty straight forward so I tried to use PointerEntered & PointerExited events to capture & release the pointer from the SelectionCanvas. And PointerMoved to change the cursor icon. But it seems that none of the events were triggering.
I tried binding to the Viewport grid element as well but no luck in that too.
I'm not sure what I missed here. Could someone please help me on this? Any help is much appreciated. Please find the complete source code here.
Please note that a sample PDF is included into the startup project /Resources which you'll have to open from the app.
The PointerEntered and PointerExited events are raised provided that the area that is supposed to raise them is painted so try to set the Background property of the Canvas to some brush like for example Transparent:
<Canvas x:Name="SelectionCanvas" CompositeMode="SourceOver"
Background="Transparent"
PointerEntered="SelectionCanvas_PointerEntered"
...

WPF user control that slides out either left or right with an array of buttons?

Firstly, I am new to WPF and have inherited a legacy application that needs improving.
I need to replace an existing single button with a new kind of user control.
Secondly, I have searched the web for WPF examples of the user control functionality I am interested in and cannot find it.
I don't think it exists, but I don't know what it is called and so I may not be searching with the correct name.
The best name I can come up with is button-slider-flyout control (hehe).
I need a user control with the same functionality as in this picture (orginal image url http://imgur.com/zGPECq6).
You will notice the picture is a character gear screen where a user has extended a slide panel for tabards. The functionality of the button slider is what I am looking for.
I suppose what I am after is something like a ComboBox with custom behaviour.
Instead of a drop-down list, I need a slide-left or slide-right list (perhaps a slide-direction property).
The list items should allow me to assign a text value but display images instead of description text.
After selecting an item, the slider should collapse and the main image should become the same as the selected items image.
The SelectedValue property should be set to the value of the selected items value.
Code should fire for the chosen item, either via the selectedindex_changed event or the items themselves could have click behaviour.
Does this user control already exist in WPF? If so what is it called?
If the control does not exist can someone please give an example of how to build it?
As an example, I can imagine the following XAML for the completed control...
<Border Grid.Row="0" ...>
<Button x:Name="moveButton" Click="moveButton_Click">
<Button.Background>
<ImageBrush ImageSource="moveIcon.png" .../>
</Button.Background>
</Button>
</Border>
<Border Grid.Row="1" ...>
<ButtonSliderFlyout x:Name="addButtonSlider" SlideDirection="Left">
<!-- DEFAULT ICON AND HAS NO CLICK BEHAVIOUR -->
<ButtonSliderFlyoutItem x:Name="addItem" Value="Add">
<ButtonSliderFlyoutItem.Background>
<ImageBrush ImageSource="addIcon.png" Stretch="Uniform"/>
</ButtonSliderFlyoutItem.Background>
</ButtonSliderFlyoutItem>
<!-- ITEM1 WITH CLICK BEHAVIOUR -->
<ButtonSliderFlyoutItem x:Name="addItem1" Value="AddItem1" Click="addItem1_Click">
<ButtonSliderFlyoutItem.Background>
<ImageBrush ImageSource="addItem1Icon.png" Stretch="Uniform"/>
</ButtonSliderFlyoutItem.Background>
</ButtonSliderFlyoutItem>
<!-- ITEM2 WITH CLICK BEHAVIOUR -->
<ButtonSliderFlyoutItem x:Name="addItem2" Value="AddItem2" Click="addItem2_Click">
<ButtonSliderFlyoutItem.Background>
<ImageBrush ImageSource="addItem2Icon.png" Stretch="Uniform"/>
</ButtonSliderFlyoutItem.Background>
</ButtonSliderFlyoutItem>
</ButtonSliderFlyout>
</Border>

Pivot overlapping other elements in WP 8.1 Universal app (and automatically changing margin)

The following XAML shows the content of a Windows Phone 8.1 Universal app page. The idea is to have a bar on top of a pivot. But the pivot is overlapping the bar whereas the sample grid in blue is working as expected.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="{StaticResource PhoneAccentBrush}" Height="50" />
<Pivot Grid.Row="1" Background="Green" Width="200" HorizontalAlignment="Left" />
<Grid Grid.Row="1" Background="Blue" Width="200" HorizontalAlignment="Right" />
</Grid>
The resulting Page looks like this:
Where is this "negative margin" coming from?
How can it be avoided?
BTW: Just setting a margin is not a solution as it introduces other problems, for example a jumping GUI when using a SemanticZoom control, I need to know the root cause of the problem to solve it...
Info: It seems that the Windows Phone Pivot automatically changes the margin depending on the current screen settings (status bar shown/hidden). So if your app changes the state of the status bar in some circumstances you will end up having a jumping/changing pivot control.
I've found a solution and created a simple attached property for the Pivot control.
The attached property can be used this way:
<Pivot controls:PivotExtensions.DisableAutoMargin="True">
<PivotItem Header="A">
...
</PivotItem>
<PivotItem Header="B">
...
</PivotItem>
</Pivot>
The class with the attached property can be found here:
http://mytoolkit.codeplex.com/SourceControl/latest#MyToolkit.Extended.WinRT/Controls/PivotExtensions.cs
Downside: You cannot override the template anymore as the attached property changes the template already...
Overriding the control template doesn't seem to work; there is some code in the control that's setting the margin after construction. Also setting the Margin on the offending grid on the Loaded event doesn't work either, the negative margin code runs after that.
The only way I found to make the odd behavior go away was to ask your UI to overlap the status bar:
ApplicationView.GetForCurrentView()
.SetDesiredBoundsMode(ApplicationViewBoundsMode.UseCoreWindow);
Then the Pivot control figures that it doesn't need to try and cover the status bar. Note that you'll now have to give room in your page layout to prevent overlap with the status bar.

Open WPF Window in StackPanel [duplicate]

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?

Focus on Canvas overlapping the listbox in WP7

I have a situation here. I have a page containing a ListBox. The ListBox is populated with Items if it is able to fetch the data from a web service. Now when the user doesn't have network connectivity on his phone or the webservice doesn't respond back with Ok status, I want to show the user a pop-up with an option to Retry or select Ok to stay on the same page (though it sounds dumb). Now for this I used a Canvas:
<Canvas Name="Nonetwork" Height="150" Width="280" HorizontalAlignment="Center" VerticalAlignment="Center" Background="DodgerBlue" Visibility="Collapsed" Margin="111,160,92,160" >
<TextBlock VerticalAlignment="Top" Height="120" Width="280" Text="No Network is currently availabe" TextAlignment="Center" TextWrapping="Wrap" Foreground="White" FontSize="28" />
<Button Margin="30, 80" Height="60" Width="100" Content="OK" FontSize="18" Click="Ok_Click"/>
<Button Margin="150, 80" Height="60" Width="100" Content="Retry" FontSize="18" Click="Retry_Click"/>
</Canvas>
Well as most of you experienced guys would have guessed, the canvas is buried inside the listbox and is not accessible when there is no network connectivity. So I have a blank page with the canvas but the user is not able to click on Ok or Retry. Please help
Please do let me know if there is any other approach to solve this problem. I tried Popup but I cant Navigate to the main page from a pop-up since that is a user control page. Any help is higly appreciated
Well, I placed my Canvas below the ListBox and the problem was solved. I didn't know that positioning of the controls in the XAML would have so much effect ...
The order in which elements are rendered in Silverlight is determined firstly by where they appear in the visual object hierarchy and secondly by their ZIndex property.
The Canvas has a third attached property named ZIndex that you can use to override the default layering of elements. Although this Canvas.ZIndex attached property is defined by the Canvas class, it actually works with any type of panel.
You can also try Canvas.ZIndex property:
Canvas.ZIndex Attached Property
What you do is a wrong practice and not at all recommended.
ChildWindow is the class you should use to display such kind of dialog.
Using a Popup is also another approach you can use.
NOTE: I know the simplest approach would be to use MessageBox.Show(), but it would create a popup out of silverlight frame and does not allow theming/styling and other customizations.

Categories