IronPython as Scripting language to C# WPF VS 2015 - c#

I'm having some trouble that I hope you can help with! I've being trying to update this grid.Width parameter in a while loop, in a sleep(500) step. But, when I hit run script on my program, the entire GUI stops. I already tried running the script on a different Thread and using BackgroundWorker, but still both ways they block my application GUI until the script is finished. Could you take a look in the following code please?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string script;
ScriptEngine engine;
ScriptScope scope;
Thread threadScript;
public MainWindow()
{
InitializeComponent();
engine = Python.CreateEngine();
scope = engine.CreateScope();
string variableName = "isto";
object gridMier = gridScript;
scope.SetVariable(variableName, gridMier);
}
public void rodarScript()
{
this.Dispatcher.Invoke((Action)(() =>
{
try
{
//PARTE PARA ADICIONAR BIBLIOTECAS BASICAS PARA DESENVOLVIMENTO COM OS SCRIPTS
script = #"#Reference the WPF assemblies
import clr
clr.AddReferenceByName(""PresentationFramework, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35"")
clr.AddReferenceByName(""PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"")
import System.Windows
def getMyObject():
return isto
objeto = getMyObject()
#Atalhos de referencias para adicionar
Thickness = System.Windows.Thickness
from System.Threading.Thread import Sleep
Debug = System.Diagnostics.Debug";
script = script + "\n" + textBoxScript.Text;
var source = engine.CreateScriptSourceFromString(script, SourceCodeKind.Statements);
//var compiled = source.Compile();
//var result = compiled.Execute(scope);
source.Execute(scope);
}
catch (Exception qualquerExcecaoEncontrada)
{
MessageBox.Show(qualquerExcecaoEncontrada.ToString(), "Scripting Test do Mier", MessageBoxButton.OK);
}
}));
}
private void buttonScript_Click(object sender, RoutedEventArgs e)
{
threadScript = new Thread(rodarScript);
threadScript.Start();
}
}
}
example of the code in IronPython (textBoxScript.Text)
for num in range(1,100):
objeto.Width = objeto.Width + 1
Sleep(500)
This simple code, running on a Thread, blocks my entire GUI for 50 seconds.
Any help would be appreciated!
Thanks,
Lucas.

Creating a seperate thread and then putting the complete content in Dispatcher.Invoke does not sence. Because you are then again sync with the ui thread (the howle time). You should only invoke those things, which needs to be (UI access). First remove that from rodarScript and only use it for script = script + "\n" + textBoxScript.Text;:
public void rodarScript()
{
try
{
//PARTE PARA ADICIONAR BIBLIOTECAS BASICAS PARA DESENVOLVIMENTO COM OS SCRIPTS
script = #"#...";
this.Dispatcher.Invoke((Action)(() =>
{
script = script + "\n" + textBoxScript.Text;
}));
var source = engine.CreateScriptSourceFromString(script, SourceCodeKind.Statements);
//var compiled = source.Compile();
//var result = compiled.Execute(scope);
source.Execute(scope);
}
catch (Exception qualquerExcecaoEncontrada)
{
MessageBox.Show(qualquerExcecaoEncontrada.ToString(), "Scripting Test do Mier", MessageBoxButton.OK);
}
}
(Removed IP-Code).
Then add some simple method, which accepts an instance of PythonFunction and add it as a variable, like this:
public void ExecuteInUI(object obj)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
var op = engine.CreateOperations(scope);
op.Invoke(obj);
}));
}
Add as variable:
scope.SetVariable("execute_in_ui", new Action<object>(ExecuteInUI));
Then you have to chagne your Python code a little bit, because you only want to use BeginInvoke, when you access the ui:
def inc_width():
objeto.Width = objeto.Width + 1
for num in range(1,100):
execute_in_ui(inc_width)
Sleep(500)
So we are passing the function information of inc_width to c# and execute it from there in ExecuteInUI. Then complete code will look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace AsyncIronPython
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string script;
ScriptEngine engine;
ScriptScope scope;
Thread threadScript;
public MainWindow()
{
InitializeComponent();
engine = Python.CreateEngine();
scope = engine.CreateScope();
string variableName = "isto";
object gridMier = gridScript;
scope.SetVariable(variableName, gridMier);
scope.SetVariable("execute_in_ui", new Action<object>(ExecuteInUI));
}
public void ExecuteInUI(object obj)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
var op = engine.CreateOperations(scope);
op.Invoke(obj);
}));
}
public void rodarScript()
{
try
{
//PARTE PARA ADICIONAR BIBLIOTECAS BASICAS PARA DESENVOLVIMENTO COM OS SCRIPTS
script = #"#Reference the WPF assemblies
import clr
clr.AddReferenceByName(""PresentationFramework, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35"")
clr.AddReferenceByName(""PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"")
import System.Windows
def getMyObject():
return isto
objeto = getMyObject()
#Atalhos de referencias para adicionar
Thickness = System.Windows.Thickness
from System.Threading.Thread import Sleep
Debug = System.Diagnostics.Debug";
this.Dispatcher.Invoke((Action)(() =>
{
script = script + "\n" + textBoxScript.Text;
}));
var source = engine.CreateScriptSourceFromString(script, SourceCodeKind.Statements);
//var compiled = source.Compile();
//var result = compiled.Execute(scope);
source.Execute(scope);
}
catch (Exception qualquerExcecaoEncontrada)
{
MessageBox.Show(qualquerExcecaoEncontrada.ToString(), "Scripting Test do Mier", MessageBoxButton.OK);
}
}
private void buttonScript_Click(object sender, RoutedEventArgs e)
{
threadScript = new Thread(rodarScript);
threadScript.Start();
}
}
}
XAML:
<Window x:Class="AsyncIronPython.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:AsyncIronPython"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="gridScript">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBox x:Name="textBoxScript" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="3" AcceptsReturn="True" AcceptsTab="True" />
<Button x:Name="buttonScript" Click="buttonScript_Click" VerticalAlignment="Center" HorizontalAlignment="Stretch" Content="Execute" Grid.Row="1" Margin="3" />
</Grid>
</Window>
Hope this helps.

Thank you #BengEg and people, that was exactly what I was looking for. I was trying to be able to create animations in textBoxes, Grids, User Controls in general, using IronPython script inside C# WPF. So, I was having trouble to find a way of doing so, since the User Controls are being used by another threads in my program. So, here is the final "Testing Scripting code".
CSharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace AsyncIronPython
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string script;
ScriptEngine engine;
ScriptScope scope;
Thread threadScript;
public MainWindow()
{
InitializeComponent();
engine = Python.CreateEngine();
scope = engine.CreateScope();
scope.SetVariable("objetoEditavel", gridScript);
scope.SetVariable("execute_in_ui", new Action<object>(ExecuteInUI));
}
public void ExecuteInUI(object obj)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
var op = engine.CreateOperations(scope);
op.Invoke(obj);
}));
}
public void rodarScript()
{
try
{
//PARTE PARA ADICIONAR BIBLIOTECAS BASICAS PARA DESENVOLVIMENTO COM OS SCRIPTS
script = #"#Reference the WPF assemblies
import clr
clr.AddReferenceByName(""PresentationFramework, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35"")
clr.AddReferenceByName(""PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"")
import System.Windows
def getMyObject():
return objetoEditavel
objeto = getMyObject()
#Atalhos de referencias para adicionar
Thickness = System.Windows.Thickness
from System.Threading.Thread import Sleep
Debug = System.Diagnostics.Debug";
this.Dispatcher.Invoke((Action)(() =>{script = script + "\n" + textBoxScript.Text;}));
var source = engine.CreateScriptSourceFromString(script, SourceCodeKind.Statements);
source.Execute(scope);
}
catch (Exception qualquerExcecaoEncontrada)
{
MessageBox.Show(qualquerExcecaoEncontrada.ToString(), "Scripting Test do Mier", MessageBoxButton.OK);
}
}
private void buttonScript_Click(object sender, RoutedEventArgs e)
{
threadScript = new Thread(rodarScript);
threadScript.Start();
}
}
}
XAML
<Window x:Class="AsyncIronPython.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:AsyncIronPython"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBox x:Name="textBoxScript" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="261,3,3,3" AcceptsReturn="True" AcceptsTab="True" Background="#FFFFD6D6" />
<Button x:Name="buttonScript" Click="buttonScript_Click" VerticalAlignment="Center" HorizontalAlignment="Stretch" Content="Execute" Grid.Row="1" Margin="3" />
<Grid x:Name="gridScript" HorizontalAlignment="Left" Height="50" Margin="10,10,0,0" VerticalAlignment="Top" Width="50" Background="Black"/>
</Grid>
</Window>
IronPython Script inside gridScript (will basically create an animation of this black box grid to grow in a interval of 50 miliseconds.
def inc_width():
objeto.Width = objeto.Width + 1
for num in range(1,100):
execute_in_ui(inc_width)
Sleep(50)

Related

DispatcherTimer does not fire

I just got started in Windows Store App development and I just wanted a very simple application: Pretty much a progres bar that fills up from left to right, but even this task is apparently not achievalbe for me.
I have the following code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace TimeLoader
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private DispatcherTimer refreshTimer;
public MainPage()
{
this.InitializeComponent();
}
void refreshTimer_Tick(object sender, object e)
{
TimePassedBar.Value += 5;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
TimePassedBar.Value = 50;
new DispatcherTimer();
this.refreshTimer = new DispatcherTimer();
this.refreshTimer.Interval = new TimeSpan(0, 0, 0, 100);
this.refreshTimer.Tick += refreshTimer_Tick;
this.refreshTimer.Start();
}
}
}
<Page
x:Class="TimeLoader.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TimeLoader"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<ProgressBar Grid.Row="0" Grid.Column="0" Height="150" Value="75" VerticalAlignment="Center" Name="TimePassedBar"/>
</Grid>
</Page>
Now the same Setup works pretty fine when I do it in WPF but the Tick Event never fires when I start this code built as a Windows store app. Is there something Special I have to pay Attention to when building Windows Store Apps? I have looked high and low and sadly have found nothing on this matter.
Your code was working fine. You just didn't wait long enough to notice. :)
private void Page_Loaded(object sender, RoutedEventArgs e)
{
TimePassedBar.Value = 50;
this.refreshTimer = new DispatcherTimer();
this.refreshTimer.Interval = TimeSpan.FromMilliseconds(100);
this.refreshTimer.Tick += refreshTimer_Tick;
this.refreshTimer.Start();
}
You are setting the TimeSpan as 100 seconds. You need to use the five-parameter overload to get milliseconds. But IMHO it's easier and more readable to just use the FromMilliseconds() method (as above).
Also, you don't need to create a DispatcherTimer object twice, especially when you're going to ignore the first one completely. :)

Best way to handle UI performance issues in Windows Phone 8.1

I seem to have a sluggish UI when trying to scroll any large TextBlocks...
What's the best way to go about this in WP 8.1?
Here's an example I made to illustrate the issue, notice when the app is ran the framerate drops horribly.
I've already looked up BackgroundWorker and it doesn't seem to exist in WP 8.1.
MainPage.xaml
<Page
x:Class="HTTPRequest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HTTPRequest"
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>
<ScrollViewer x:Name="scroll" Margin="10,13,0,10" Width="380" MaxZoomFactor="4" VerticalScrollMode="Enabled" HorizontalScrollMode="Disabled" IsTapEnabled="False">
<TextBlock x:Name="RSSData" TextWrapping="Wrap" Text="Loading..." FontSize="22" VerticalAlignment="Top"/>
</ScrollViewer>
<ProgressBar x:Name="prog" Height="16" Margin="101,310,101,0" VerticalAlignment="Top" IsIndeterminate="True"/>
</Grid>
</Page>
MainPage.xaml.cs
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=391641
namespace HTTPRequest
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
Main();
}
private async void Main()
{
string results = await DownloadXMLDocument();
prog.Visibility = Visibility.Collapsed;
RSSData.Text = results;
}
public async Task<string> DownloadXMLDocument()
{
string URLString = "http://www.packtpub.com/rss.xml";
Uri uri = new Uri(URLString);
XmlDocument xmlDocument = await XmlDocument.LoadFromUriAsync(uri);
return xmlDocument.GetXml();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
}
}
There is a known issue with large quantities of text in a single TextBox. Instead try using the RichTextBox and see if your performance improves. Sorry you had a problem.
Best of luck!

Media element not playing audio in windows store app

I want to play mp3 audio in my app but nothing is happening
my code is this
XAML:
<Page
x:Class="SunnahForKids.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SunnahForKids"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Black">
<StackPanel Width="900" Height="700" HorizontalAlignment="Center">
<MediaElement HorizontalAlignment="Left" Name="a" AutoPlay="False" Source="azan.mp3" Height="100" Margin="451,299,0,0" VerticalAlignment="Top" Width="100" Volume="100"/>
<Button Content="Button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,676,0" Height="189" Click="Button_Click"/>
</StackPanel>
</Grid>
</Page>
And here is my .cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Data.Json;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Media.SpeechSynthesis;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace SunnahForKids
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
a.Play();
}
}
}
and I am struggling with it for 2 days need help . I also followed this link MediaElement in WinRT / Win8 does not work at all
to update my driver but it is up to date.Display driver in Intel R(Q35) express chipset family ( Microsoft Corporation WDDM-1.0) please get me out of here..
I tried your code and the code works, so something strange is going on. I would try to listen for the events mentioned in the link (example further down for devs looking for code example).
Check your event log on the computer (Windows => Applications), if you've missed updates for windows, and check that that mp3 will otherwise play.
Listen for the MediaFailed event (recommend that you do in the docs) and see if you can grab some information there.Code from msdn:
private void videoMediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
// Check the event arguments => e
// get HRESULT from event args
string hr = GetHresultFromErrorMessage(e);
// Handle media failed event appropriately
}
private string GetHresultFromErrorMessage(ExceptionRoutedEventArgs e)
{
String hr = String.Empty;
String token = "HRESULT - ";
const int hrLength = 10; // eg "0xFFFFFFFF"
int tokenPos = e.ErrorMessage.IndexOf(token, StringComparison.Ordinal);
if (tokenPos != -1)
{
hr = e.ErrorMessage.Substring(tokenPos + token.Length, hrLength);
}
return hr;
}

Accessing a control - Missing a using directive or assembly reference

I am using WPF application in C# and I want at the beginning to draw a triangle.
This is the error that appears when I run the program:
'WpfApplication1.mainWindow' does not contain a definition for
'mainViewport' and no extension method for 'mainViewport' accepting a
first argument of type 'WpfApplication1.mainWindow' could be found.
(are you missing a using directive or an assembly reference?)
Here is my XAML page:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF 3D Chart" Height="455" Width="689">
<Grid>
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="100"
LookDirection="-11,-10,-9"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="11,10,9"
FieldOfView="70" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight
Color="White"
Direction="-2,-3,-1" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
</Window>
and this is my code: (the error appears on the last line of my code)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
System.Windows.Media.Media3D.Point3D point0 = new Point3D(-0.5, 0, 0);
System.Windows.Media.Media3D.Point3D point1 = new Point3D(0.5, 0.5, 0.3);
System.Windows.Media.Media3D.Point3D point2 = new Point3D(0, 0.5, 0);
System.Windows.Media.Media3D.MeshGeometry3D triangleMesh = new MeshGeometry3D();
triangleMesh.Positions.Add(point0);
triangleMesh.Positions.Add(point1);
triangleMesh.Positions.Add(point2);
int n0 = 0;
int n1 = 1;
int n2 = 2;
triangleMesh.TriangleIndices.Add(n0);
triangleMesh.TriangleIndices.Add(n1);
triangleMesh.TriangleIndices.Add(n2);
System.Windows.Media.Media3D.Vector3D norm = new Vector3D(0, 0, 1);
triangleMesh.Normals.Add(norm);
triangleMesh.Normals.Add(norm);
triangleMesh.Normals.Add(norm);
System.Windows.Media.Media3D.Material frontMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Blue));
System.Windows.Media.Media3D.GeometryModel3D triangleModel = new GeometryModel3D(triangleMesh, frontMaterial);
triangleModel.Transform = new Transform3DGroup();
System.Windows.Media.Media3D.ModelVisual3D visualModel = new ModelVisual3D();
visualModel.Content = triangleModel;
this.mainViewport.Children.Add(visualModel); //here appears the error
}
}
}
You are refering to the Viewport in the constructor. At that moment in time the Viewport has not been created yet.
Use the Loaded event handler of the Window like this
<Window x:Class="WpfApplication1.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"
Loaded="Window_Loaded">
<Grid>
Do NOT leave the constructor empty! There is an important call in there! The InitializeComponent loads the UI of the Window.
As far as I can see you removed that call in your code and that causes the code to break as well. Use the Loaded handler, that is what is for.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
Your XAML creates a class named WPFChart.Window1 while your code modifies a class called WpfApplication1.MainWindow. I don't know which one is right, but you need to change one of them so they match.

Yet another WPF external .csv binding dilemma

I am having trouble displaying a my data in DataGrid.
I've searched online and found one of the possible solutions or so it seems but still no luck.
I was wondering if you could tell me what's wrong with the code?
FIY: I am loading a .csv into DataTable and then exporting it to DataGrid.
Here is my code:
// DataLoader is a class that loads the data from .csv data file. I've tested it and it works for sure.
// MainWindow.xampl.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.IO;
namespace Splash
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DataLoader dataTable = new DataLoader();
public MainWindow()
{
InitializeComponent();
}
private void Data_Table(object sender, SelectionChangedEventArgs e)
{
string path = #"C:\Users\Lyukshins\Dropbox\PROGRAM_TEST\AUTOMATION\DATA\Database.csv";
FileInfo theFile = new FileInfo(path);
dataTable = new DataLoader();
DataTable table = dataTable.GetDataTableFromCsv(theFile);
dataGrid.ItemsSource = table.DefaultView;
dataGrid.AutoGenerateColumns = true;
}
private void Copy_Files_Click(object sender, RoutedEventArgs e)
{
}
private void Rename_Click(object sender, RoutedEventArgs e)
{
}
}
}
// XAML
<Window x:Class="Splash.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Splash" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="386" d:DesignWidth="1000" SizeToContent="WidthAndHeight" Name="Splash" ResizeMode="CanResizeWithGrip" Background="#FFBFDEBF">
<Grid>
<DataGrid Height="335" HorizontalAlignment="Left" Name="dataGrid" VerticalAlignment="Top" Width="475" SelectionChanged="Data_Table"/>
<Button Content="Copy Files" Height="54" HorizontalAlignment="Left" Margin="504,12,0,0" Name="Copy_Files" VerticalAlignment="Top" Width="301" Click="Copy_Files_Click" Foreground="Black" FontStyle="Normal" Background="LightSteelBlue" />
<Button Content="Rename Files" Height="54" HorizontalAlignment="Left" Margin="833,12,0,0" Name="Rename" VerticalAlignment="Top" Width="114" Click="Rename_Click" Background="LightSteelBlue" />
<Button Content="Distribute Files From Vendors" Height="235" HorizontalAlignment="Left" Margin="504,81,0,0" Name="Distribute_Files_From_Vendors" VerticalAlignment="Top" Width="301" Background="LightSteelBlue" />
<Button Content=" Create Project
Folders" Height="235" HorizontalAlignment="Left" Margin="833,81,0,0" Name="Create_Apollo_File_Structure" VerticalAlignment="Top" Width="114" HorizontalContentAlignment="Center" Background="LightSteelBlue" AllowDrop="False"></Button>
</Grid>
</Window>
It seemed that the problem was solved by setting
dataGrid.ItemsSource = table.DefaultView;
dataGrid.AutoGenerateColumns = true;
but it didn't work in my case.
Could you please help?
I was able to get the solution to the problem elsewhere.
The basic idea is that I failed to write a display function.
By simply adding function private void viewGrid(DataTable table) it solved my problem.
Here is the updated code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.IO;
namespace Splash
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DataLoader dataTable = new DataLoader();
public MainWindow()
{
string path = #"C:\Users\Lyukshins\Dropbox\PROGRAM_TEST\AUTOMATION\DATA\Database.csv";
FileInfo theFile = new FileInfo(path);
dataTable = new DataLoader();
DataTable table = dataTable.GetDataTableFromCsv(theFile);
InitializeComponent();
viewGrid(table);
}
private void viewGrid(DataTable table)
{
if (table.Columns.Count == 0)
MessageBox.Show("Error!");
else
dataGrid.ItemsSource = table.DefaultView;
}
private void Data_Table(object sender, SelectionChangedEventArgs e)
{
string path = #"C:\Users\Lyukshins\Dropbox\PROGRAM_TEST\AUTOMATION\DATA\Database.csv";
FileInfo theFile = new FileInfo(path);
dataTable = new DataLoader();
DataTable table = dataTable.GetDataTableFromCsv(theFile);
}
private void Copy_Files_Click(object sender, RoutedEventArgs e)
{
}
private void Rename_Click(object sender, RoutedEventArgs e)
{
}
}
}

Categories

Resources