ProgressBar in Silverlight Custom Splash Screen - silverlight

How does one embed the Silverlight ProgressBar control in a a custom splash screen? I put the following into loose xaml (simplified for brevity):
<Grid xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ProgressBar />
</Grid>
The error message is as follows:
Error: Unhandled Error in Silverlight Application
Code: 2007
Category: ParserError
Message: Unknown element: ProgressBar.
etc
Isn't the ProgressBar a standard control defined in the http://schemas.microsoft.com/winfx/2006/xaml/presentation namespace?

I'm assuming SL2 or SL3 since the presence of a progress bar - it got added in SL2.
The /winfx/2006/xaml/presentation name space isn't declared - but certainly in SL2/3 that is where it resides. You have used the alternative http://schemas.microsoft.com/client/2007, this is a legacy namespace for SL1.0
The code given will work, but to reproduce I have to have the root element as a user control and the namespaces have to reside in there, otherwise the usercontrol tag itself is not recognised.
<UserControl x:Class="myApp.scratchpad"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<ProgressBar />
</Grid>
</UserControl>
Worked fine in SL3.
Can you post more of the page, root element, update the reference to the SL2/3 namespace and also say which verison of SL is being used?

If this is for the SplashScreenSource property of the object tag, then the XAML must be Silverlight 1+JavaScript (non-managed XAML) Here is how you would do that: (Taken from the Silverlight SDK here)
<Canvas Background="Black" Width="302" Height="52">
<Rectangle Canvas.Left="1" Canvas.Top="1" Width="300" Height="30" Fill="White"/>
<Rectangle x:Name="progressBarFill" Canvas.Left="1" Canvas.Top="1" Height="30" Fill="Blue"/>
</Canvas>
And then use a JS function to update the progress:
function onProgressChanged(sender, eventArgs)
{
var slPlugin = sender.getHost();
slPlugin.content.findName("progressBarFill").width = eventArgs.progress * 300;
}

Related

Using SVG image in WPF project as Canvas background [duplicate]

Can someone describe a recommended Step by Step procedure for doing this?
Step1. Convert SVG to XAML... thats easy
Step2. Now what?
Your technique will depend on what XAML object your SVG to XAML converter produces. Does it produce a Drawing? An Image? A Grid? A Canvas? A Path? A Geometry? In each case your technique will be different.
In the examples below I will assume you are using your icon on a button, which is the most common scenario, but note that the same techniques will work for any ContentControl.
Using a Drawing as an icon
To use a Drawing, paint an approriately-sized rectangle with a DrawingBrush:
<Button>
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<Drawing ... /> <!-- Converted from SVG -->
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Button>
Using an Image as an icon
An image can be used directly:
<Button>
<Image ... /> <!-- Converted from SVG -->
</Button>
Using a Grid as an icon
A grid can be used directly:
<Button>
<Grid ... /> <!-- Converted from SVG -->
</Button>
Or you can include it in a Viewbox if you need to control the size:
<Button>
<Viewbox ...>
<Grid ... /> <!-- Converted from SVG -->
</Viewbox>
</Button>
Using a Canvas as an icon
This is like using an image or grid, but since a canvas has no fixed size you need to specify the height and width (unless these are already set by the SVG converter):
<Button>
<Canvas Height="100" Width="100"> <!-- Converted from SVG, with additions -->
</Canvas>
</Button>
Using a Path as an icon
You can use a Path, but you must set the stroke or fill explicitly:
<Button>
<Path Stroke="Red" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>
or
<Button>
<Path Fill="Blue" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>
Using a Geometry as an icon
You can use a Path to draw your geometry. If it should be stroked, set the Stroke:
<Button>
<Path Stroke="Red" Width="100" Height="100">
<Path.Data>
<Geometry ... /> <!-- Converted from SVG -->
</Path.Data>
</Path>
</Button>
or if it should be filled, set the Fill:
<Button>
<Path Fill="Blue" Width="100" Height="100">
<Path.Data>
<Geometry ... /> <!-- Converted from SVG -->
</Path.Data>
</Path>
</Button>
How to data bind
If you're doing the SVG -> XAML conversion in code and want the resulting XAML to appear using data binding, use one of the following:
Binding a Drawing:
<Button>
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<DrawingBrush Drawing="{Binding Drawing, Source={StaticResource ...}}" />
</Rectangle.Fill>
</Rectangle>
</Button>
Binding an Image:
<Button Content="{Binding Image}" />
Binding a Grid:
<Button Content="{Binding Grid}" />
Binding a Grid in a Viewbox:
<Button>
<Viewbox ...>
<ContentPresenter Content="{Binding Grid}" />
</Viewbox>
</Button>
Binding a Canvas:
<Button>
<ContentPresenter Height="100" Width="100" Content="{Binding Canvas}" />
</Button>
Binding a Path:
<Button Content="{Binding Path}" /> <!-- Fill or stroke must be set in code unless set by the SVG converter -->
Binding a Geometry:
<Button>
<Path Width="100" Height="100" Data="{Binding Geometry}" />
</Button>
Install the SharpVectors library
Install-Package SharpVectors
Add the following in XAML
<UserControl xmlns:svgc="http://sharpvectors.codeplex.com/svgc">
<svgc:SvgViewbox Source="/Icons/icon.svg"/>
</UserControl>
Windows 10 build 15063 "Creators Update" natively supports SVG images (though with some gotchas) to UWP/UAP applications targeting Windows 10.
If your application is a WPF app rather than a UWP/UAP, you can still use this API (after jumping through quite a number of hoops): Windows 10 build 17763 "October 2018 Update" introduced the concept of XAML islands (as a "preview" technology but I believe allowed in the app store; in all cases, with Windows 10 build 18362 "May 2019 Update" XAML islands are no longer a preview feature and are fully supported) allowing you to use UWP APIs and controls in your WPF applications.
You need to first add the references to the WinRT APIs, and to use certain Windows 10 APIs that interact with user data or the system (e.g. loading images from disk in a Windows 10 UWP webview or using the toast notification API to show toasts), you also need to associate your WPF application with a package identity, as shown here (immensely easier in Visual Studio 2019). This shouldn't be necessary to use the Windows.UI.Xaml.Media.Imaging.SvgImageSource class, though.
Usage (if you're on UWP or you've followed the directions above and added XAML island support under WPF) is as simple as setting the Source for an <Image /> to the path to the SVG. That is equivalent to using SvgImageSource, as follows:
<Image>
<Image.Source>
<SvgImageSource UriSource="Assets/svg/icon.svg" />
</Image.Source>
</Image>
However, SVG images loaded in this way (via XAML) may load jagged/aliased. One workaround is to specify a RasterizePixelHeight or RasterizePixelWidth value that is double+ your actual height/width:
<SvgImageSource RasterizePixelHeight="300" RasterizePixelWidth="300" UriSource="Assets/svg/icon.svg" /> <!-- presuming actual height or width is under 150 -->
This can be worked around dynamically by creating a new SvgImageSource in the ImageOpened event for the base image:
var svgSource = new SvgImageSource(new Uri("ms-appx://" + Icon));
PrayerIcon.ImageOpened += (s, e) =>
{
var newSource = new SvgImageSource(svgSource.UriSource);
newSource.RasterizePixelHeight = PrayerIcon.DesiredSize.Height * 2;
newSource.RasterizePixelWidth = PrayerIcon.DesiredSize.Width * 2;
PrayerIcon2.Source = newSource;
};
PrayerIcon.Source = svgSource;
The aliasing may be hard to see on non high-dpi screens, but here's an attempt to illustrate it.
This is the result of the code above: an Image that uses the initial SvgImageSource, and a second Image below it that uses the SvgImageSource created in the ImageOpened event:
This is a blown up view of the top image:
Whereas this is a blown-up view of the bottom (antialiased, correct) image:
(you'll need to open the images in a new tab and view at full size to appreciate the difference)
After various searches and attempts I managed to find the method without having to use external libraries.
First you will need to use Inkscape to open the SVG file to prepare, then follow the procedure according to the following list:
Open the SVG file with Inkscape;
Press Ctrl + A to select everything;
Go to Edit > Resize page to selection;
Press Ctrl + C;
Press Ctrl + S then close Inkscape;
Open the SVG file a file editor then go to <path>, you could view several paths. This is an example:
<path d="..." fill="..." id="path2"/>
<path d="..." fill="..." id="path4"/>
<path d="..." fill="..." id="path6"/>
In your XAML file you have to create a ViewBox element, then insert a Grid element and then Path elements for the number of times when in the SVG file see the paths:
<Viewbox Stretch="Fill">
<Grid>
<Path Fill="..." Data="..."/>
<Path Fill="..." Data="..."/>
<Path Fill="..." Data="..."/>
</Grid>
</Viewbox>
Where in Fill property on your XAML you have to insert the fill property in the SVG file and in Data property on your XAML you have to insert the d property in the SVG file.
You should get a result like this:
Option 1: Use SVG icons directly using "SharpVectors" nuget package
Add SharpVectors nuget package to your project.
Add SVG files to your project, for example, in a "Icons" subfolder and set their Build Action property to Resource
Use it in your code:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<Button Height="100">
<svgc:SvgViewbox Source="/Icons/Checkmark_16x.svg"/>
</Button>
<ContentControl Height="100">
<svgc:SvgViewbox Source="/Icons/CollapseAll_16x.svg"/>
</ContentControl>
<Label Height="100">
<svgc:SvgViewbox Source="/Icons/Refresh_16x.svg"/>
</Label>
</StackPanel>
</Grid>
</Window>
Option 2: Convert SVG to XAML using "SvgToXaml" tool
SvgToXaml. Download the latest release (this answer was tested with the "Ver_1.3.0")
Place all your SVG icons into a folder and execute the following command:
SvgToXaml.exe BuildDict /inputdir "c:\Icons" /outputdir "c:\MyWpfApp" /outputname IconsDictionary
Add generated IconsDictionary.xaml file to your project and use it in your code:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="IconsDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<StackPanel>
<Button Height="100">
<Image Source="{StaticResource Refresh_16xDrawingImage}"/>
</Button>
<ContentControl Height="100">
<Image Source="{StaticResource CollapseAll_16xDrawingImage}"/>
</ContentControl>
<Label Height="100">
<Image Source="{StaticResource Checkmark_16xDrawingImage}"/>
</Label>
</StackPanel>
</Grid>
</Window>
Option 3: Use IValueConverter for some already generated XAML files
If you already have generated XAML files and you want to use them, for some types of them it is possible to create a custom ValueConverter class. Please refer to the following answers for more information:
Option 2: Use .xaml icon files directly
https://stackoverflow.com/a/21588195/7585517
You can use the resulting xaml from the SVG as a drawing brush on a rectangle. Something like this:
<Rectangle>
<Rectangle.Fill>
--- insert the converted xaml's geometry here ---
</Rectangle.Fill>
</Rectangle>
Use the SvgImage or the SvgImageConverter extensions, the SvgImageConverter supports binding.
See the following link for samples demonstrating both extensions.
https://github.com/ElinamLLC/SharpVectors/tree/master/TutorialSamples/ControlSamplesWpf
We can use directly the path's code from the SVG's code:
<Path>
<Path.Data>
<PathGeometry Figures="M52.8,105l-1.9,4.1c ...
Another alternative is dotnetprojects SVGImage
This allows native use of .svg files directly in xaml.
The nice part is, it is only one assembly which is about 100k. In comparision to sharpvectors which is much bigger any many files.
Usage:
...
xmlns:svg1="clr-namespace:SVGImage.SVG;assembly=DotNetProjects.SVGImage"
...
<svg1:SVGImage Name="mySVGImage" Source="/MyDemoApp;component/Resources/MyImage.svg"/>
...
That's all.
See:
https://www.nuget.org/packages/DotNetProjects.SVGImage/
https://github.com/dotnetprojects/SVGImage
I found this tutorial extremely helpful: https://msadowski.github.io/WPF-vector-graphics-tutorial/
Download the zip file for the program from github.
Use program to convert the SVG to XAML.
Copy/paste the .xaml file into your folder of choice in your project.
Add the application resource to App.xaml for your file.
Reference your vector image in your xaml page with Source="{StaticResource }"
The tutorial explains all steps very well with an example shown. I've tried it and my svg image is showing up great in my application now.

Mahapp Flyout is hidden by webview2 control

I feel like I'm missing something obvious, but:
I was hoping to use the mahapps Flyout control to do a fairly simple flyout over a webview2 control. However, the the flyout shows behind the webview2 control, leaving most of the flyout hidden.
The control is wrapped in a Grid in the code below because I noticed that if I put the webview in a StackPanel, then the webview doesn't show (no height/width measurements given) but the flyout does appear in front as expected. So I tried DockPanel and Grid which show the webview page but hide the flyout.
The hatched area on the right of the screenshot is so the user has a mouseover area which should auto expand the flyout:
And this is how the flyout renders whether webview is without a wrapper, or in a DockPanel or Grid:
<mah:MetroWindow x:Class="Fraxinus.EdBoard.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Fraxinus.EdBoard.UI"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<VisualBrush x:Key="MyVisualBrush" TileMode="Tile" Viewport="0,0,5,5" ViewportUnits="Absolute" Viewbox="0,0,5,5" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Background="Black">
<Path Data="M 0 5 L 5 0" Stroke="Gray" />
<Path Data="M 0 0 L 5 5" Stroke="Gray" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Window.Resources>
<mah:MetroWindow.Flyouts>
<mah:FlyoutsControl Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2">
<mah:Flyout x:Name="flyout" Position="Right">
<TextBlock Text="Some Text"/>
</mah:Flyout>
</mah:FlyoutsControl>
</mah:MetroWindow.Flyouts>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="98*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
<wv2:WebView2 Source="http://localhost:4200"></wv2:WebView2>
</Grid>
<StackPanel Grid.Column="1" Grid.Row="0" MouseEnter="StackPanel_MouseEnter" MouseLeave="StackPanel_MouseLeave" Background="{StaticResource MyVisualBrush}">
</StackPanel>
</Grid>
</mah:MetroWindow>
Also is it a simple thing to prevent the flyout from extending into the title bar?
Thanks, Luke
Yep: I have the exact same problem with MahApps Metro async dialogs displaying underneath. Menus and Context Menus work fine although the latter isn't styled like the former which is a real bummer and headache to do.
Glad I didnt try the Hamburger Menu: besides I dont want my WebView2 based Javascript Web Map to have to resize itself on every flyout of this menu if heavily loaded with serious maps!
I'll try styling the Context Menu but the answer is that I am seriously thinking of just doing all of the menus and dialogs in JavaScript leaving just the WebView2 plus Mahapps shell with an Hamburger icon which I did get working. As I can always just use JS to C# interop to do processing with C# libraries in the effective back end in which I case I could go with Photino but then I wouldn't be able to use my Hamburger icon in the MetroWindow Title Bar so I will stick with it. Decisions. Decisions..
This is the definitive answer to use of WebView2: menus, context menus, or else JavaScript menus and dialogs for everything. Although I am pretty sure regular Windows popup dialogs or custom ones in their own windows will work but again you will have to style them and I am beginning to think that styling in JS and CSS will be one hell of a lot easier!
From the Ticket AirHack looks to be the only other option but requires re-inheriting all of your controls = nope!

WPF Usercontrol based on Textbox/Popup definition

I created a "UserControl" based on a TextBox. That means I created a new UserControl and replaced UserControl by TextBox in xaml and xaml.cs files.
Now I want that my new TextBox control shall have a popup to display some suggestions.
Now my question is: Where can I define the look/structure of the Popup as XAML? The Popup definition shall be part of the newTextBox.
That's what I have:
<TextBox x:Class="WpfApplication11.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication11"
mc:Ignorable="d"
MaxWidth="{Binding Path=ActualWidth}">
</TextBox>
I think you're totally missing what a UserControl actually is. To put it simply, a UserControl is a group or collection of controls that make up one larger... uh... control.
I want that my new TextBox control shall have a popup to display some suggestions.
What you are describing here is a UserControl. You cannot place a Popup inside a TextBox.
So. What you're after here is probably something like this:
<UserControl ... >
<Grid>
<TextBox Name="txt"
Width="150" ... />
<Popup PlacementTarget="{Binding ElementName=txt}"
Placement="Bottom"
IsOpen="True"
StaysOpen="True"
Width="{Binding ActualWidth, ElementName=txt}">
<!-- Some popup content here -->
</Popup>
</Grid>
</UserControl>
This is obviously an extremely simplified example, but you get the idea.

How can I center the title of a WPF RibbonWindow?

I want to center the title of my RibbonWindow, and not have it aligned on the side.
This thread said it had an answer:
Center WPF RibbonWindow Title via XAML Code
but it didn't work.
Bellow is an image and the corresponding code.
<RibbonWindow x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Ribbon>
<Ribbon.TitleTemplate>
<DataTemplate>
<TextBlock TextAlignment="Center" HorizontalAlignment="Stretch" Width="{Binding ElementName=Window, Path=ActualWidth}">ApplicationTitle
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="0" Color="MintCream " BlurRadius="10" />
</TextBlock.Effect>
</TextBlock>
</DataTemplate>
</Ribbon.TitleTemplate>
</Ribbon>
</Grid>
</RibbonWindow>
I am using VS 2012, with .NET 4.5 and the included System.Windows.Controls.Ribbon assembly.
Had a bad experience with using RibbonControlsLibrary for WPF. It has issues not only around title centering. It also breaks window rounding corners at the top, icon and title goes out of the screen when maximized, and personally I haven't found any chance to program ribbon group dialog. All of this lead me to searching for an alternative, and I have found a Fluent Ribbon Controls Suite
Download source code and build it for .NET 4.5 (I did it with absolutely no issues).
The ElementName in the binding (Width="{Binding ElementName=Window, Path=ActualWidth}") needs to match the name of the RibbonWindow. So, in this case you need "Window" for the name:
<RibbonWindow x:Class="Window1" x:Name="Window"
... />

Scrollbar of a webbrowser control doesn't work correctly if enclosed in a tabcontrol

I have a program that has use of a webbrowser control. When enclosed in the main grid something like this:
<grid>
<WebBrowser x:Name="webBrowser" .../>
</grid>
The scrollbars work like they should, it goes to the extremes of the page.
however in if i want to put the webbrowser control in a tabcontrol, say because i wanted a tabbed browser, with the code like this
<grid>
<tabcontrol ...>
<tabitem ... >
<grid....>
<webBrowser x:Name="webBrowser1" />
</grid>
</tabitem>
</grid>
The scrollbars of the webbrowser control are not scrolling to the ends of the page, instead it it stops about 10% from the end horizontally and vertically.
Is there a way to get s tabbed browsercontrol that doesn't truncate the page?
Here is the more detailed code
<tabcontrol Height="500" HorizontalAlignment="Left" Margin="0,272,0,0" Name="tabControl1" VerticalAlignment="Top" Width=1000>
<Tabitem Header="FlexWebApp" Name="FWA" scrollViewer.VerticalSchollBarVisibility="Auto">
<grid Schrollviewer.VerticalScrollbarvisibility="hidden" name="FWAGrid>
<WebBrowser Name="WFWA" Source="pathToApplication"/>
</Grid>
</TabItem>
<TabItem header= AnalyseFWA Name="AFWA ...>
<Tabitem Header="SLWebApp" Name="SLA" scrollViewer.VerticalSchollBarVisibility="Auto">
<grid Schrollviewer.VerticalScrollbarvisibility="hidden" name="SLAGrid>
<WebBrowser Name="WSLA" Source="pathToApplication"/>
<TabItem header= AnalyseSLA Name="ASLA ...>
</Grid>
</TabItem>
So if it's not apparent the webbrowsers are directed to one silverlight app and one flex app both apps get truncated. In fact on both cases, the grid that encloses the apps' scrollbar is always visible despite the hidden attribute.
The truncation does not occur on regular browsers.
Could it be that the apps are misreporting its size?
Can you post more of your XAML?
I couldn't duplicate your issue. I created a new WPF Application project in Visual Studio 2010 and changed only the XAML and I did not have this issue.
<Window x:Class="TestBrowser.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>
<TabControl>
<TabItem Header="Rhyous.com">
<Grid>
<WebBrowser x:Name="WebBrowser" Source="http://www.rhyous.com"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>
The entire web page was displayed.
So my guess is that you will see the same if you create a sample project. Then you can start adding what you did in your real project to your sample until you find what is really breaking it.

Resources