I am currently working with SharpDx for a project that targets Win 8.1 and requires multiple 3D viewports on a page, along with other xaml elements. I have so far been able to install the SharpDx toolkit via Nuget, and been able to run a standard toolkit project. However the project uses the SwapChainBackgroundPanel control as the method of rendering the 3D content, shown below.
MainPage.xaml
<SwapChainBackgroundPanel
x:Class="MyGame1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyGame1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="1280"
d:DesignHeight="800">
</SwapChainBackgroundPanel>
MainPage.xaml.cs
public sealed partial class MainPage
{
private readonly MyGame1 game;
public MainPage()
{
this.InitializeComponent();
game = new MyGame1();
this.Loaded += (sender, args) => game.Run(this);
}
}
According to documentation I read, the SwapChainBackgroundPanel has been deprecated in favour of the newly introduced SwapChainPanel, however when I attempted to replace the SwapChainBackgroundPanel with the SwapChainPanel, I received an error.
Does anyone know if there is a plan in the immediate future to update the SharpDx toolkit to work with the SwapChainPanel in the same manner as it currently does with the SwapChainBackgroundPanel?
Thanks!
The DirectX 11.2 build already fully supports integration with SwapChainPanel.
I have added a sample that demonstrates this feature.
First, make sure your project references DirectX 11.2 assemblies - this involves project editing, as described here.
After this, edit your page xaml as needed, for example like this (some code is omitted for brevity):
<Page ...>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<SwapChainPanel x:Name="panel" x:FieldModifier="private" />
</Grid>
</Page>
Then you need to run your game as usual like this:
using SharpDX.Toolkit;
public sealed partial class MainPage
{
private readonly Game _game;
public MainPage()
{
InitializeComponent();
_game = new MiniCubeGame();
_game.Run(panel);
}
}
You can move the _game.Run(...) call to Loaded event handler if this fits better your architecture.
Related
I am trying to use C# and XAML to create a simple app for the Universal Windows Platform (UWP). When I run it, my program is supposed to display a button that will play a sound using speech synthesis when clicked. The button shows up when I run the program, but does nothing instead of following the command.
Here is the code for "mainpage.xaml", the UI design code with some of the button's parameters:
<Page
x:Class="App.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Button Content="Hello world!" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0"/>
</Grid>
Here is the code for "MainPage.xaml.cs" that contains the event handler for the button:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
//The event handler
private async void Button_Click(object sender, RoutedEventArgs e)
{
MediaElement mediaElement = new MediaElement();
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello, World!");
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
}
}
}
I would like to know:
Am I missing anything in my program? If so, what?
Does the current playback device selected for my computer affect whether the sound plays?
Is the problem caused by the event handler in general or the command itself?
Information that might be useful:
There are no build errors that keep the program from running
My operating system is Windows 10, version 1803 (Build 17134.286)
The version of C# I am using is 7.3
I am using Visual Studio 2017
This is the tutorial I followed to create my app
You need to wire up the Click event and its handler. Either in XAML or in code behind.
In XAML,
<Button Click=“Button_Click” ...
In code behind (you need to give the button a name like btn)
btn.Click += Button_Click;
Currently i am using a simple PictureBox with GIF file inside and wonder if this is possible and if it does what the differences between this 2 options
This is what i have at this moment using PictureBox:
pictureBox1.BringToFront();
pictureBox1.Dock = DockStyle.None;
pictureBox1.Visible = true;
You can try hosting SilverLight inside Winforms.
While SilverLight is intended to be used in a web browser, WPF is more native to desktop, and WPF does have a simimar BusyIndicator, it is downloadable from CodePlex-Extended WPF Toolkit.
First define a WPF user control MyBusyIndicator.
<UserControl x:Class="Stackoverflow.MyBusyIndicator"
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:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<xctk:BusyIndicator IsBusy="True" />
</Grid>
</UserControl>
Then you can host this user control in Winform using an ElementHost, first you add the ElementHost from Form's designer, and in Form's constructor
public partial class MyForm : Form
{
public MyForm ()
{
InitializeComponent();
this.elementHost1.Child = new Stackoverflow.MyBusyIndicator();
}
}
The differences:
While BusyIndicator comes with some properties to let you customize the indicator, it adds a dependency on SL or WPF. With PictureBox all you need to do is preparing animated GIFs. There are many tools for generating animated GIFs.
So I'm pretty new to WPF and MVVM, and while I understand the premise, a lot of this stuff is like trying to read hieroglyphs for me.
Basically, my situation is this: I'm using Activiz, a c# wrapper for VTK, which is an image processing/visualization library. So, in this library, there's a WinForms control called vtk:RenderWindowControl, which is an opengl control containing the class that handles all of the visualization functionality. I think it'd be easier to just use WinForms, but that's not really an option for me.
So, to use vtk:RenderWindowControl in a WPF application, I just need to shove it into a WindowsFormsHost and then I can use it more or less just like the example code, in the code behind (if that's the correct term for the .xaml.cs file)
That's fine for a test app, but in practice, I'd like to follow MVVM if possible. This is where I've run into a wall. If "renderControl" lives in the View class, how can I reference it and use it from the ViewModel? I think binding is the answer to that question, but I only really know how to do that for simple types and commands.
Following ideas in another thread I found, I managed to set up something like this answer
My codebehind looks like this:
public partial class RenderPanel_View : UserControl
{
public static readonly new DependencyProperty RWControlProperty =
DependencyProperty.Register("RWControl", typeof(RenderWindowControl), typeof(RenderPanel_View), new PropertyMetadata(null));
public RenderWindowControl RWControl
{
get { return (RenderWindowControl)GetValue(RWControlProperty); }
set { SetValue(RWControlProperty, value); }
}
public RenderPanel_View()
{
// This is necessary to stop the rendercontrolwindow from trying to load in the
// designer, and crashing the Visual Studio.
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) {
this.Height = 300;
this.Width = 300;
return;
}
InitializeComponent();
this.RWControl = new RenderWindowControl();
this.RWControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.WFHost.Child = this.RWControl;
}
}
My .xaml looks like this
<UserControl x:Class="vtkMVVMTest.RenderPanel.RenderPanel_View"
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:vtk="clr-namespace:Kitware.VTK;assembly=Kitware.VTK"
xmlns:rp="clr-namespace:vtkMVVMTest.RenderPanel"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
RWControl="{Binding VMControlProperty}">
<Grid>
<WindowsFormsHost x:Name ="WFHost"/>
</Grid>
</UserControl>
So two things. One, That last line of the xaml header is an error, "The member 'RWControl' is not recognized or accessible". I don't really understand why. Second, for what I'm guessing is the ViewModel half of the equation, how is VMControlProperty supposed to be defined?
Am I at least on the right track here, or is this way off base?
Some controls are not MVVM friendly and you have make the ViewModel aware of View interface and allow interact with it directly. Do not open the whole control to the ViewModel it will ruin the ability to write tests, put an interface on top for example IRenderPanelView and open in the interface only the functionality you need to access from ViewModel. You can then create a DP property of this type in the view, set it in the constructor and bind it to ViewModel.View property in xaml.
So I am using the WPFShell to apply chrome to a custom window. I have learned from this article that in order to use it, I have to reference the Microsoft.Windows.Shell library and use this XAML code:
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="43"
CornerRadius="25,25,10,10"
GlassFrameThickness="0">
</shell:WindowChrome>
</shell:WindowChrome.WindowChrome>
My question is, how do I enable chrome by using C# code and not XAML? (i.e. How do I apply chrome in code-behind?)
Ah, stupid me. It was easy:
WindowChrome.SetWindowChrome(this, new WindowChrome());
I know that this is a older question, But I noticed that I couldn't get WindowChrome.GetWindowChrome() to work in .NET 4.5. I'm not sure if this has to do with System.Windows.Shell being included within the PresentationFramework assembly. But since it kept returning null there would be no way to update the chrome.
So my solution was to add a 'Name' to the WindowChrome which made it accessible in Code Behind.
XAML:
<Window x:Class="SomeProject.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"
mc:Ignorable="d"Title="Some Window" WindowStyle="None" ResizeMode="CanResize"
AllowsTransparency="True">
<WindowChrome.WindowChrome>
<WindowChrome x:Name="chrome" ResizeBorderThickness="6" CaptionHeight="0"
GlassFrameThickness="0" CornerRadius="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
</window>
Code Behind:
using System;
using System.Window;
namespace SomeProject
{
public partial class MainWindow: Window
{
public MainWindow()
{
//Get Existing 'WindowChrome' Properties.
var captionHeight = chrome.CaptionHeight;
//Set Existing 'WindowChrome' Properties.
chrome.GlassFrameThickness = new Thickness(2d);
//Assign a New 'WindowChrome'.
chrome = new System.Windows.Shell.WindowChrome();
}
}
}
I hope this helps someone who needs it.
I want to embed the current Gecko in my WPF-Project.
I know there is the possibility with the Winforms-Host and the Skybound-Gecko-Library.
But I do not use the standard wpf-theme for my application. It is another and the scrollbar of the control will not be styled. Furthermore, this is an old library which is designed for Firefox 3.
Which is the best library/strategy to use the current Gecko in WPF?
You should have a look at these options, they all use Chromium:
paid: (Awesomium-based)
http://awesomium.com/ (is free for startups)
http://wpfchromium4.codeplex.com/ (uses awesomium)
free: (Chrome Embedded Framework-based)
https://github.com/chillitom/CefSharp (provides WinForms and WPF, but uses CEF1)
https://bitbucket.org/xilium/xilium.cefglue/wiki/Home (uses CEF3, and therefore supports Chrome's multi-process model, flash plugin, and WebGL)
You can probably use WindowsFormsHost, tutorial here
https://nhabuiduc.wordpress.com/2014/09/18/geckofx-net-webbrowser-setup-and-features/
the interesting part is
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
host.Child = browser;
gridWeb.Children.Add(host);
WebKit.Net is free: http://sourceforge.net/projects/webkitdotnet/
Their GitHub page seems to have been more recently updated: https://github.com/webkitdotnet
Here is my answer. As stated by Roman, Gecko is Winforms-based, not WPF-based and so has to be incorporated via the WindowsFormsHost.
After creating the Visual Studio project, install the Gecko package via NuGet, using the command: Install-Package Geckofx45
Make sure the WindowsFormsIntegration and System.Windows.Forms references have been added to your project.
In your Configuration Manager, set your configuration to 32-bit, to get rid of the compiler warnings.
Update MainWindow.xaml 'Grid' element to give it a name and the handler for the 'Loaded' event
<Grid
Name="GridWeb"
Loaded="Window_Loaded">
</Grid>
Modify MainWindow.xaml.cs to incorporate the Gecko as well as make it navigate to a page on loading:
public MainWindow()
{
InitializeComponent();
Gecko.Xpcom.Initialize("Firefox");
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
host.Child = browser;
GridWeb.Children.Add(host);
browser.Navigate("http://www.google.com");
}
I struggle using the SO code editor, so for more detailed explanations and screenshots, see this blog page.
This is an old question, but I came up with a pseudo-solution to add GeckoFX as a XAML tag such as:
<local:GeckoBrowser Width="400" Height="250" />
This can be accomplished by simply wrapping the whole thing in a UserControl such as:
XAML:
<UserControl x:Class="WpfApp1.Browser"
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:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border x:Name="border" Background="Black" Margin="0"></Border>
</UserControl>
C#:
public partial class Browser : UserControl
{
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
public Browser()
{
InitializeComponent();
Xpcom.Initialize("Firefox");
browser.Navigate("http://www.google.com");
host.Child = browser;
border.Child = host;
}
}
Now, you can use the tag in WPF, in the same project where the UserControl exists.
I have been trying to get this to work as a Control in a library, so I can easily port it to any other project/solution, but it keeps giving me an error about mozglue.dll missing. I suspect this is due to the Xpcom.Initialize("Firefox") but I need to investigate further.