How to embed web application into windows app with custom behavior - c#

I need to embed a standard webapp inside a windows app container.
The container just needs to be a wrapper around a webkit or similar rendering engine (I would like to avoid using IE rendering engine if possible) and it would contain some minimal window management logic - things like being borderless with no titlebars, being able to fix position and size, and custom overlay/always-on-top rules based on currently focused window.
I've been looking at node-webkit and it seems to fit the bill as far as containing a webapp is concerned, but I'm not sure I would be able to do the latter.
Can this be done with node-webkit, is there some other approach that would fit my use case better? I have absolutely no idea how windows app development is done, so I would appreciate some help.

If you are using WPF, you can create you window with something like this (xaml):
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None"
Title="MainWindow" Left="100" Top="200" Height="350" Width="525" PreviewKeyDown="Window_PreviewKeyDown">
<Grid x:Name="grdBrowserHost">
</Grid>
</Window>
WindowStyle attr None means "borderless with no titlebars" window. Left and Top are for position, and Width and Height are self-explanatory. All those properties can be accessed via code-behind with simple this.Width, etc... PreviewKeyDown I put here because in this example (as you will see), Topmost property will be changed from code behind (dynamically).
Code-behind should look something like
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
System.Windows.Controls.WebBrowser browser = new System.Windows.Controls.WebBrowser();
// you can put any other uri here, or better make browser field and navigate to desired uri on some event
browser.Navigate(new Uri("http://www.blic.rs/"));
grdBrowserHost.Children.Add(browser);
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
this.Close();
}
else
{
this.Topmost = !this.Topmost;
}
}
}
}
In this example I have created default WebBrowser control for showing html. If you want some other web rendering engine you must find 3rd-part control and include it in your references. For webkit, you can check How to use WebKit browser control in WPF

What you need is "UWP Bridge for web apps" ;-)
Look in the Windows Dev Center:
UWP Bridge for web apps - Create your app now

Related

CS0103 Error in Visual Studio on simple project containing only a textbox and button

UPDATE * My error had to do with the computer I was using and not being part of a FIPS validated algorithm. That error only appeared after I closed Visual Studio and tried to compile the default blank WPF form. I did the exact same thing on a personal computer and it compiled as expected. *
I'm familiar with creating windows form using C#. I looked into methods to change the look of my forms, similar to using skins, and was told that it would be easier if I I used WPF....ok.
In an effort to become familiar with WPF, I picked up a book, "MASTERING_WINDOWS_PRESENTATION_FOUNDATION" and it was slow moving with a discussion on MVVM and data binding (new topics to me). I felt the I could learn the difference between WPF and Windows Forms much faster if I first tried to create a simple WPF application. Then, as I read, I could see how something done in a very familiar way using Windows Forms, is done using WPF.
Unfortunately, I'm stuck right out the box!
Using VS2017, I created a new WPF App (.NET Framework) I then added a text box and a button. I created a name for both as this does not appear to be automatically created like with Windows Forms. I then double click on the button and a method block is created in the MainWindow.xaml.cs file. I proceed to add text to the textbox
(txtbox_1.Text="Hello;").
I noticed a few things:
1.) The InitializeComponent(); call in the MainWindow() method is underlined and corresponds to the CS0103 Error
2.) Intellisense did not recognize the textbox. I typed out the full name and it created an error when I was done. (Same CS0103 Error)
I looked through stackoverflow but found articles about Xamarin. I've heard of this as a way to write code for Android but do not know how it relates to what I'm trying to do.
What am I missing?
Here is my XAML file:
<Window x:Class="WpfApp4.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:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button x:Name="btn_browse" Content="Button" HorizontalAlignment="Left" Margin="524,91,0,0" VerticalAlignment="Top" Width="75"/>
<TextBlock x:Name="txtbox_1" HorizontalAlignment="Left" Margin="134,93,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="20" Width="363"/>
</Grid>
</Window>
And here is my MainWindow.xaml.cs file:
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void SimpleMethod()
{
txtbox_1.Text = "Hello";
}
}
}
That InitializeComponent(); line is hugely significant since it is that instruction makes your xaml turn into UI.
If it's underlined then your partial class for code behind isn't matching up with the xaml.
You will have something like
Either that or you're missing some fundamental references should have been added when you started your project.
I suggest you just bin your sln though.
Just delete it and start again.
Create a new wpf project.
Hit f5.
If it crashes and burns your VS install is broken.
Anyone and everyone will tell you to learn MVVM. And you should.
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx?Redirected=true
https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx?Redirected=true
That means that your MainWindow class actually does not inherit from System.Windows.Window class.
I don't see a reference to System.Windows in your class. This is the namespace, where the WPF Window basic class is defined. So your Window base class can reference a Window class from some other namespace, and, that's why it has no InitializeComponents() method and can not reference the property from XAML. Try first adding this using directive to code behind class. If that doesn't do the task, check if your project has a reference to System.Windows. If there is no System.Windows in your reference manager (this could be if your project is set to compile in .NET 4.0) add references to PresentationFramework, PresentationCore and WindowsBase.
The error had to do with the work computer I was using ... something to do with FIPS. You should be able to create a new WPF project and compile the blank form without error. I did the exact same thing on a personal computer and it compiled as expected. I was also able to reproduce a WinForms project as a WPF using code behind without error. Implementation using MVVM took a significant amount of time since the concept of view models was new to me but, in the end, it's not bad.

SwfPlayer in WPF application : Shockwave not found

First of all, I work in C# / XAML on Visual Studio C# 2013 Express.
I write today for a swf player in a wpf application. I read many discuss on this subjetcs but no one can solve my problem. I use a PageSwitcher, each page inherit from UserControl class and I create a button for each .swf file in a directory. This work fine. When I click on one of them, I want to open a new page wich is the swf viewer. I can open a new page, but my pdf viewer not work. I tried many ways to resolve my problem, but nothing work. I have a WinForm application wich do what I want, but I can't add it in my WPF application I try a WindowsFormHost but I still have the same error : Type or namespace 'AxShockwaveFlashObjects' not found, whereas I add AxInterop.ShockwaveFlashObjects.dll and/or Interop.ShockwaveFlashObjects.dll
Here is my code :
XAML
<UserControl x:Class="WPFPageSwitch.swf"
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:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
mc:Ignorable="d">
<Grid x:Name="Container">
</Grid>
</UserControl>
C#
namespace WPFPageSwitch
{
public partial class swf : System.Windows.Controls.UserControl, ISwitchable
{
public swf(string swf)
{
InitializeComponent();
System.Windows.Forms.Integration.WindowsFormsHost swfPlayer = new System.Windows.Forms.Integration.WindowsFormsHost();
AxShockwaveFlashObjects.AxShockwaveFlash axShockwaveFlash = new AxShockwaveFlashObjects.AxShockwaveFlash();
swfPlayer.Child = axShockwaveFlash;
Container.Children.Add(swfPlayer);
}
}
}
Somebody can help me ?
The error is here : AxShockwaveFlashObjects.AxShockwaveFlash axShockwaveFlash = new AxShockwaveFlashObjects.AxShockwaveFlash();
Add a reference to it.
AxShockwaveFlashObjects is a COM library to allow you to integrate Flash content into your .NET application. Demo Here

MVVM Light & WPF - Binding Multiple instances of a Window to a ViewModel

I am working on my first project in MVVM and I've chosen to use the MVVM Light Toolkit. I have a GameViewModel that handles business on the main screen of my game. I need to find out how to open a new window (AdventurerView) with an instance of Adventurer as a parameter when a command is executed, have it bound to AdventurerViewModel, and display and return data. Instances of this window will be opened and closed frequently. I have been stuck on this for a couple of days now and it's driving me crazy. I would like to learn how to do this in an MVVM-friendly way, preferably with the tools provided by MVVM Light or pure XAML.
I've tried using MVVM Light's ViewModelLocator but since AdventurerView is a window it won't work; it says "Can't put a Window in a Style", though the program still compiles and runs. Could there be something I could change to make that work? Or is there another way to bind them in XAML? Or another approach entirely? I would really love to be able to move on from this. I have also tried using MVVM Light's messenger to no avail (which still doesn't tackle the View/ViewModel issue).
I just need to be able to create a window that is bound to AdventurerViewModel and display/return the appropriate data.
AdventurerView.xaml is in its default state at the moment, but I feel that if I could bind the appropriate data that might help (DataContext).
AdventurerViewModel is pretty bare-bones as well
class AdventurerViewModel : ViewModelBase
{
#region Members
private Adventurer _adv;
#endregion
#region Properties
public Adventurer Adv
{
get { return _adv; }
set { _adv = value; }
}
#endregion
#region Construction
public AdventurerViewModel(Adventurer adv)
{
this._adv = adv;
}
#endregion
}
App.xaml with the non-working DataTemplate at the bottom:
<Application StartupUri="MainWindow.xaml"
xmlns:views="clr-namespace:AoW.Views"
xmlns:vm="clr-namespace:AoW.ViewModels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AoW.App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<DataTemplate DataType="{x:Type vm:GameViewModel}">
<views:GameView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TitleViewModel}">
<views:TitleView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:AdventurerViewModel}">
<views:AdventurerView />
</DataTemplate>
</Application.Resources>
</Application>
The command in GameViewModel that will hopefully make this all happen (the messagebox just confirms that the command is firing):
private void ExecuteShowAdvCommand(Adventurer adv)
{
System.Windows.MessageBox.Show(adv.Name);
}
I don't really know what else to include.
Ok I put together a demo that should make this hopefully easier for you Download Link
Functionality:
3 Windows in Total (MainWindow, ModalWindow, NonModalWindow)
MainWindow has a TextBox you can type whatever you want into.
2 buttons on the top will open the Modal / NonModal Window accordingly
Each window when opened will display the message that was in MainWindow's TextBox in a TextBlock inside them.
In each window you can tick a CheckBox to update the value in result's textblock in MainWindow (For the Modal Window this will kick in when modal window is closed. For NonModal changes can be seen asap)
That's it for functionality,
Concepts:
Registering Multiple VM's with the SimpleIoC and using GetInstance(...) to request them out.
Messenger class usage with a custom message type OpenWindowMessage
Opening Modal / Non Modal Windows from a parent VM staying true to the MVVM principles
Passing data between windows(just shown in NonModal)
Important Note:
- The method used in this example to set the non DP DialogResult from the modal window is not MVVM friendly cos it uses code-behind to set the DialogResult property on a Window.Closing event which should be avoided(If needing to be "testable"). My preferred approach is a bit long and is very well documented HERE(Mixture of question and answer). Hence why I ignored it for the sake of this sample.
Follow up to Viv, I modified the sample to include an example of opening the window without using a code behind.
Sample project is here.
I'm utilizing the ViewModelLocator singleton with a static method that news up the viewmodel and window and Data Context instead of the code behind.
Blog Post with Details.
Let me know which method is preferable. I dislike using code behind, but there could be pro's and con's I'm missing.

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

How to put a custom windows forms control in a WPF application?

As a short term solution I'm trying to jam a windows form 'usercontrol' into a WPF application. I see in the WPF application view that I can add a 'custom windows form control' to the project and it makes an empty custom control, but I can't figure out how to add it. Ideally I'd like to know how to take the .dll from my compiled windows forms user control and stick it into the WPF app, or import the user control into the WPF application.
Thanks,
Sam
You can't really add it as a control to the toolbox like you could for a Windows Forms Application. What you should do instead is "host" the user control inside of the WPF application.
See how to do it on MSDN.
Here's an example of how to use a masked text box (which you can easily modify to use your custom control):
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="HostingWfInWpf">
<Grid>
<WindowsFormsHost>
<wf:MaskedTextBox x:Name="mtbDate" Mask="00/00/0000"/>
</WindowsFormsHost>
</Grid>
</Window>
Add a reference to System.Windows.Forms and WindowsFormsIntegration to your Project
xmlns:WinForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:WindowsFormsIntegration="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
And place Windows forms host in the window.
<WindowsFormsHost Name="wfhDate"
HorizontalAlignment="Center"
VerticalAlignment="Stretch">
<WinForms:FlowLayoutPanel/>
</WindowsFormsHost>
Now in C# code
using Forms = System.Windows.Forms;
.........................
Forms.FlowLayoutPanel flpPanel = this.wfhDate.Child as Forms.FlowLayoutPanel;
// Initialize your Forms contol here.
flpPanel.Controls.Add( yourControl );
Lucas' answer is correct, but I wanted to add something needed. If you are creating a web application, then you must change the Security setting to This is a full trust application. I could not get the WindowsFormsHost control to work prior to doing this.

Categories