Problems with webviewbrush and Rectangle - c#

I'm having problems hiding a webview, my application is based on a webview as I'm showing words definitions with an html format, when I need to show any settings pane or any other element over the webview I need to hide it and fill a rectangle with a webviewbrush...
The problem is that when I do it, the rectangle shows an stretched image... I've tried using different stretch settings both for the webview brush and rectangle but can't make it look exactly like the webview...
For example if I use stretch none on the webviewbrush.. it works under some resolutions, but on higher resolutions it shows the image bigger than it is...
I can't seem to find a fix for this... could anybody give me a hand?

Try the MSDN-Example, it works well on my project. If it doesen't work create a new clean project and try it without your additional xaml maybe you mest up some properties ;-)
XAML:
<Grid>
<WebView x:Name="contentView" Source="http://www.contoso.com"/>
<Rectangle x:Name="contentViewRect"/>
</Grid>
Code behind:
private void AppBar_Opened(object sender, object e)
{
WebViewBrush wvb = new WebViewBrush();
wvb.SourceName = "contentView";
wvb.Redraw();
contentViewRect.Fill = wvb;
contentView.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
private void AppBar_Closed(object sender, object e)
{
contentView.Visibility = Windows.UI.Xaml.Visibility.Visible;
contentViewRect.Fill = new SolidColorBrush(Windows.UI.Colors.Transparent);
}

Related

UWP Programatically change background image of XAML page c#

I have been searching for a while and honestly I haven't solved this really simple issue. I have a flyout menu and I have attached an event to a flyout menu item. I want to change programmatically the background image of my XAML page when I select the item.
<Grid x:Name="main">
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="Assets/bg_1.jpg"/>
</Grid.Background>
</Grid>
This is the default image I got as a background (the grid is basically the whole page).
The C# event code is here:
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
main.Background = new ImageBrush { ImageSource = new BitmapImage(new Uri("ms-appx:///MTG Life Counter/Assets/bg_2.jpg")) , Stretch = Stretch.None};
}
When I select the menu item instead of setting the image as background, it makes it white.
Default background
I tested and it is not an issue of the image. I know that I am doing something like an obvious mistake but I am a bit new to UWP and I couldn't find a solution.
Here is the blank background after I select to change it
Thanks for you time and sorry for the ignorance.
there's a property called "BaseUri"... try adding it to your code.
make these changes:
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
main.Background = new ImageBrush { ImageSource = new BitmapImage(new Uri(this.BaseUri, "Assets/bg_2.jpg")), Stretch = Stretch.None };
}

Passing a string parameter to a textblock

I am trying to pass a string parameter from another xaml page (upon click of a button) into a content dialog and display it inside a textblock in another colour.
Example of the textblock text:
Hey -parameter in red colour-, well -parameter in blue colour-, ... some text... -parameter in another colour-
My current method is to create several textblocks with different properties and then programmatically set the text to the corresponding textblock in the constructor.
There are too much redundant code and I believe there is a more elegant solution to this and I hope that someone could point me in the correct direction. Something tells me its binding but I am not sure how to proceed. (I'm new to XAML and trying to figure my way out by starting on something simple)
You can have an object set as the ContentDialog.DataContext and then use binding to achieve what you want.
In your Button.Click handler, set the data context:
private void Button_Click(object sender, RoutedEventArgs args)
{
ContentDialog dialog = new ContentDialog
{
DataContext = new
{
RedText = "Red Colour",
BlueText = "Blue Colour"
}
};
dialog.ShowAsync();
}
Then in the XAML of the ContentDialog, you can have something as:
<ContentDialog>
<TextBlock>Hey <TextBlock Background="Red" Text="{Binding RedText}"/>, well <TextBlock Background="Blue" Text="{Binding BlueText}"/></TextBlock>
</ContentDialog>

Alternate ways to display forms inside a Grid row in WPF

The WPF application I've created contains a Grid with 3 rows. I have a set of buttons in the 3rd row. On Clicking the Buttons, the forms are displayed in the 2nd row of the Grid. However What I've done is quite messy because I've created all the form contents in the same window and have set the visibility to Hidden.
sample code:
<Grid Name="panel1" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
<Grid Name="panel2" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
<Grid Name="panel3" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
My xaml Code looks like this:
private void Image_MouseLeftButtonDown_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
panel1.Visibility = System.Windows.Visibility.Hidden;
panel2.Visibility = System.Windows.Visibility.Visible;
panel3.Visibility = System.Windows.Visibility.Hidden;
}
This approach looks really messy as I've included all the code in the Main Xaml file.
Need some alternate ways to do this. Kindly help.
Create a method like this
private void VisibilityManager(Grid grd)
{
new List<Grid>(){ panel1, panel2, panel3}
.ForEach(x => x.Visibility = Visibility.Hidden);
grd.Visibility = Visibility.Visible;
}
and call it like this
VisibilityManager(panel1);
for making panel1 visible and all other hidden.
In future if you have to increase your grids just make changes inside this method.
You could style a tabcontrol and switch the tab, you could use a contentcontrol and create a binding to the content you want to show. You could also use a databinding (depends on what you want to display) and use a template selector... there are many ways to solve that problem. Just tell a bit more what your contents look like

Toolbar Overlay over WindowsFormsHost

I have a SWF object embedded in a WindowsFormsHost Control inside a WPF window.
I'd like to add a toolbar over the swf movie.
The problem with the snippet of code I have below, is that when the new child is added to the host control (or the movie is loaded, I haven't figured out which yet), the toolbar is effectively invisible. It seems like the z-index of the swf is for some reason set to the top.
Here is what it looks like:
XAML:
<Grid Name="Player">
<WindowsFormsHost Name="host" Panel.ZIndex="0" />
<Grid Name="toolbar" Panel.ZIndex="1" Height="50"
VerticalAlignment="Bottom">
[play, pause, seek columns go here]
</Grid>
</Grid>
C#:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
flash = new AxShockwaveFlashObjects.AxShockwaveFlash();
host.Child = flash;
flash.LoadMovie(0, [movie]); // Movie plays, but no toolbar :(
}
Any insight on this issue would be much appreciated.
Update: Since no suitable answer was posted, I've placed my own solution below. I realize this is more of a hack than a solution so I'm open to other suggestions.
Here is my hackaround the WindowsFormsHost Z-index issue.
The idea is to place whatever you need to be overlayed nested inside a Popup. Then to update that popup's position as per this answer whenever the window is resized/moved.
Note: You'll probably also want to handle events when the window becomes activated/deactivated, so the pop disappears when the window goes out of focus (or behind another window).
XAML:
<Window [stuff]
LocationChanged="Window_LocationChanged"
SizeChanged="Window_SizeChanged" >
<Grid Name="Player">
[same code as before]
<Popup Name="toolbar_popup" IsOpen="True" PlacementTarget="{Binding ElementName=host}">
[toolbar grid goes here]
</Popup>
</Grid>
</Window>
C#:
private void resetPopup()
{
// Update position
// https://stackoverflow.com/a/2466030/865883
var offset = toolbar_popup.HorizontalOffset;
toolbar_popup.HorizontalOffset = offset + 1;
toolbar_popup.HorizontalOffset = offset;
// Resizing
toolbar_popup.Width = Player.ActualWidth;
toolbar_popup.PlacementRectangle = new Rect(0, host.ActualHeight, 0, 0);
toolbar_popup.Placement = System.Windows.Controls.Primitives.PlacementMode.Top;
}
private void Window_LocationChanged(object sender, EventArgs e)
{ resetPopup(); }
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{ resetPopup(); }
Another solution I've discovered is to use Windows Forms' ElementHost control. Since I'm using a Windows Form inside a WPF window anyway, why not just use an entire Windows Form and save myself Z-Issue headaches.
The ElementHost control is really useful, because I can still use my toolbar UserControl, and embed it inside the Windows Form. I've discovered that adding a child can be finicky with Windows Forms, so here's a snippet describing the solution:
First, toss in the ActiveX object, then an ElementHost Control, using the designer.
Form1.Designer.cs:
private AxShockwaveFlashObjects.AxShockwaveFlash flash;
private System.Windows.Forms.Integration.ElementHost elementHost1;
Form1.cs
public Form1(string source)
{
InitializeComponent();
toolbar = new UserControl1();
this.elementHost1.Child = this.toolbar;
this.flash.LoadMovie(0, source);
}
Note that the child was not set in the designer. I found that for more complex UserControls the designer will complain (though nothing happens at runtime).
This solution is, of course, still not entirely ideal, but it provides the best of both worlds: I can still code my UserControls in XAML, but now I don't have to worry about Z-indexing issues.

Metro Tile Notifications in C#

I'm trying to put together a simple Windows 8 metro style app in c# with tile notifications but I can't seem to get them working.
What I can't quite figure out yet is where the code to update the tile notifications should reside. I've had a look at the Javascript sample, but I'm not seeing how that works in a C# app. Has anyone got some sample code or a quick tip on where tile updates should happen in a C# metro app?
My understanding is that every app decides where to do this for itself. Normally, you'd do it whenever you're also updating your normal UI with the same data - e.g. if your app is an RSS reader, and you've just downloaded a new item to display, that's where you also update your tile by posting a notification. In the sample JavaScript app, this is done from event handlers for controls for the sake of convenience.
As for the code to change the tile, it should be almost identical to JavaScript version, since in both cases you use Windows.UI.Notifications namespace. Following is a very simple C# app that updates the tile when you click the button. XAML:
<UserControl x:Class="TileNotificationCS.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
d:DesignHeight="768" d:DesignWidth="1366">
<StackPanel x:Name="LayoutRoot" Background="#FF0C0C0C">
<TextBox x:Name="message"/>
<Button x:Name="changeTile" Content="Change Tile" Click="changeTile_Click" />
</StackPanel>
</UserControl>
and code behind:
using System;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
namespace TileNotificationCS
{
partial class MainPage
{
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
public MainPage()
{
InitializeComponent();
}
private void changeTile_Click(object sender, RoutedEventArgs e)
{
XmlDocument tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText01);
XmlElement textElement = (XmlElement)tileXml.GetElementsByTagName("text")[0];
textElement.AppendChild(tileXml.CreateTextNode(message.Text));
tileUpdater.Update(new TileNotification(tileXml));
}
}
}
Don't forget that you need a wide tile for text to show up - to get it, set some image for "Wide Logo" in Package.appxmanifest.
Make sure you change the Initial rotation to Landscape, set some image for Widelogo, and use this method to set the text along with an expiry.
void SendTileTextNotification(string text, int secondsExpire)
{
// Get a filled in version of the template by using getTemplateContent
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText03);
// You will need to look at the template documentation to know how many text fields a particular template has
// get the text attributes for this template and fill them in
var tileAttributes = tileXml.GetElementsByTagName("text");
tileAttributes[0].AppendChild(tileXml.CreateTextNode(text));
// create the notification from the XML
var tileNotification = new TileNotification(tileXml);
// send the notification to the app's default tile
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
}
Here is a detailed explanation http://www.amazedsaint.com/2011/09/hellotiles-simple-c-xaml-application.html

Categories