Using the WaveformTimeline Control in the WPF Sound Visualisation Library - c#

I am having problems using the WaveformTimeLine class in the WPF Sound Visualization Library using the NAUDIO class library.I have followed the instructions they have put out in their documentation but it's just not working for me.
My code behind looks like:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private OpenFileDialog dialogBox = new OpenFileDialog();
private void open_Click(object sender, RoutedEventArgs e)
{
//Get Audio File
dialogBox.Filter = "Wave File (*.mp3 ; *.wav) | *.mp3;*.wav;";
if (dialogBox.ShowDialog() == true)
{
NAudioEngine.Instance.OpenFile(dialogBox.FileName);
fileLocation = dialogBox.FileName;
}
var soundEngine = NAudioEngine.Instance;
soundEngine.PropertyChanged += NAudioEngine_PropertyChanged;
soundEngine.OpenFile(fileLocation);
if (NAudioEngine.Instance.CanPlay) NAudioEngine.Instance.Play();
myWave = new WaveformTimeline();
myWave.RegisterSoundPlayer(soundEngine);
}
The code doesn't throw any errors but it also doesn't do anything too.Can someone with experience with this API or similar APIs please help me solve this problem.

Key mistake was the line
myWave = new WaveformTimeline();
After adding the WaveformTimeline control in XAML design view, you don't initialise the control again in the code behind because you will be given another instance of the WaveformTimeline object.

Related

Trying to make the method of a button click use variable in WPF

I am new to WPF and Coding in general, I am trying to create a small UI to read and write data on .txt files. All the reading part functions works well but now I am having trouble making a small UI to display the information found in the .txt files.
My problem is more with how button clicks work in WPF. All the data is stored in the forms of object of class Static_Data_Scheme and Dynamic_Data_Scheme inside the program, these class are just simple collection of Dictionaries Objects. Part of my data is 'static' meaning it will be stored in .txt files that won't change location and so can be loaded when the program is started, and another part of my data is 'Dynamic' meaning it can be stored anywhere and the file path can be changed using a file explorer in the program. Important thing to note, the Static_Data_Scheme is needed to generate the Dynamic_Data_Scheme.
My initial way of handling it when I made the program to test it out was to generates both Data Scheme with the same button press called load, but since the static dictionaries can be loaded right at the start of the program I want to try and add that method to the MainWindow instead and only have the program generates the Dynamic_Data_Scheme when I press the load button, but I'm unable to find any documentation on how to add arguments to the click method of the button.
Current code that works but that I don't like due to the fact that Static_Data_Scheme.Start method is called each time the load button is pressed and could instead be loaded only once when the program starts :
public MainWindow()
{
InitializeComponent();
}
private void Save_Loader_Click(object sender, RoutedEventArgs e)
{
Static_Data_Scheme static_Data_Scheme = new Static_Data_Scheme();
static_Data_Scheme = static_Data_Scheme.Start();
Dynamic_Data_Scheme dynamic_Data_Scheme = new Dynamic_Data_Scheme();
Save_Parser.Parse_Save(#"file_path", static_Data_Scheme, ref dynamic_Data_Scheme);
}
What I wanna try to achieve is something like that :
public MainWindow()
{
InitializeComponent();
Static_Data_Scheme static_Data_Scheme = new Static_Data_Scheme();
static_Data_Scheme = static_Data_Scheme.Start();
}
private void Save_Loader_Click(object sender, RoutedEventArgs e)
{
Dynamic_Data_Scheme dynamic_Data_Scheme = new Dynamic_Data_Scheme();
Save_Parser.Parse_Save(#"file_path", static_Data_Scheme, ref dynamic_Data_Scheme);
}
But this doesn't work due to the fact that the Save_Parser.Parse_Save method lack the static_Data_Scheme variable and I can't add it to the Save_Loader_Click method either.
So my question is how do I tell my ave_Loader_Click method to get the static_Data_Scheme from the program?
You almost had it, just move the variable outside of your method:
Static_Data_Scheme static_Data_Scheme = new();
public MainWindow()
{
InitializeComponent();
/* static_Data_Scheme = ???? */static_Data_Scheme.Start();
}
private void Save_Loader_Click(object sender, RoutedEventArgs e)
{
var Data_Scheme = new Dynamic_Data_Scheme();
Save_Parser.Parse_Save(#"file_path", static_Data_Scheme, ref dynamic_Data_Scheme);
}

How to run a C# winform in an XNA C# project

I am trying to use the PDFsharp library in an XNA game. The example code I am trying to get to work is:
static void Main()
{
Renderer renderer = new Renderer();
PreviewForm form = new PreviewForm();
form.RenderEvent = new PagePreview.RenderEvent(renderer.Render);
Application.Run(form);
}
But I don't know how to get this to run in XNA.
Is it possible to pass the graphics that are passed to the winform to the XNA graphics engine instead?
update 2
It appears that the original links to MSDN have been broken, I can't seem to find them on MSDN anymore, if someone does, please update the post. In the mean time you may want to check out this codeproject article -- http://www.codeproject.com/Articles/21330/Easy-Rendering-with-XNA-Inside-a-Windows-Form
update after a quick check, looks like the first link at (See also: XNA and WinForms) is the same one I found.
I recommend you look into mixing winforms and XNA, try this: http://create.msdn.com/en-US/education/catalog/sample/winforms_series_1
The First thing you need to do is to create the login form.
in this form create the fields you need as public properties
public string userName {get;set;}
public string password {get;set;}
in the login form you need to write the user info to those properties:
private void btnOk_Click(object sender,EventArgs e)
{
this.userName = txtName.Text;
this.password = txtPass.Text;
this.Close();
}
then, in the game (in the part you need) write something like this:
using (var form = new frmLogin())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
string user = form.userName;
string pass = form.password;
}
}
But as an FYI - winforms don't look so good in XNA
Hope it helps

c# - WPF command-line argument for opening file gives infinite loop

This is a weird one! I am working on an application that reads vCard files, which contain contact etc. information for a person. Each file may contain separate 'sections' that each contain the details for one person, which are separated by BEGIN:VCARD [data here] END:VCARD.
To enable my users to view all of the different details, I've allowed my program to populate the textboxes in my app with the details and then open a new Window and do this with that one, but for each of the different sections in the file.
The problem comes about when my program opens when a vCard file has been double clicked in Explorer. It keeps looping through the vCard. I don't know what to do, but below is my problematic code:
public void readVcard(string fname)//Reads vCard and then loops through sections
{
try
{
using (StreamReader r = new StreamReader(fname))
{
string input = File.ReadAllText(fname);//read through file
String[] vArray = input.Split(new string[] { "BEGIN:VCARD" }, StringSplitOptions.None);
int i;
for (i = 1; i < vArray.Length; i++)
{
MainWindow a = new MainWindow();
a.parser(vArray[i]); //Parser is the function that populates the app
a.Show();
}
return;
}
}...
This function is called from here:
void MainWindow_Loaded(object sender, RoutedEventArgs e)//Processes a file when opened externally
{
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
readVcard(fname);
}
}
If anyone could help, it would be greatly appreciated.
I think that Artyom is on the right track.
Every time you create another MainWindow and load it you will be getting the current applications argurment and jumping back in to readVcard, which will process the same vCard that you are already processing and open yet another MainWindow which will continue the process.
Consider moving all of the code you have inside of MainWindow_Loaded() to the Startup event for your application. That way it will only get called once when your program first loads, instead of every time you create a new window.
To do this you need to register for the event in your App.xaml file like so:
<Application x:Class="MyProgram.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
</Application>
And then in the code behind App.xaml you put your code for reading the vCard. Like this:
namespace MyProgram
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
readVcard(fname);
}
}
}
}
When you create and show new MainWindow (a.Show()), the MainWindow_Loaded event fires again and it again calls a readVcard method. So there is an infinite loop.
Or may be not really infinite, because, I belive, some time later a StackOverflowException may happen.
You just need to review startup logic, so readVcard will launch not in the MainWindow_Loaded event, but, for example, in the Main method (in program.cs file). Or you may add some flag, which will be set when readVcard method first called.
I get it! I've now got the following code in App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (e.Args != null && e.Args.Count() > 0)
{
this.Properties["ArbitraryArgName"] = e.Args[0];
}
base.OnStartup(e);
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
MainWindow mw = new MainWindow();
mw.readVcard(fname);
}
}
}
It works fine! Thanks everyone. BTW the following blog contains the command-line info I originally used if anyone needs it: http://blogs.msdn.com/b/avip/archive/2008/10/27/wpf-supporting-command-line-arguments-and-file-extensions.aspx.

How do I get the About box to appear in C#?

I have an About box in my C# project using Microsoft's Visual C# 2008 Express Edition named AboutBox1. I have made it look how I want it in the design view, but how do I make it appear when the About link in the Help menu is clicked?
This codes makes an About box appear, but it looks blank. It's not the one I designed.
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox1 box = new AboutBox1();
box.ShowDialog();
}
Any thoughts or suggestions would be appreciated. Thanks.
Got it.
The about box is driven off of assembly properties for your project.
Go to Project -> 'ProjectName' Properties -> Assembly Information.
You set all of the information there.
If you try to set the information in the Property Explorer it will simply be over written at run time by what ever is in this window.
Cheers,
Mike
It sounds to me like a borked designer surface... have you hit save and rebuilt it? Perhaps close the IDE, reopen it, and check that your carefully designed form is still pretty?
BTW, when using ShowDialog you should also use using (since it doesn't Dispose() itself when shown with ShowDialog):
using(AboutBox1 box = new AboutBox1()) {
box.ShowDialog(this);
}
Did you remove the method-call to 'InitializeComponent' in the constructor of your AboutBox - form ?
Your constructor should at least look like this:
public partial class AboutBox : Form
{
public AboutBox()
{
InitializeComponent ();
}
}
Where the InitializeComponent method call should be the first line in the constructor.
If it appears but is blank, the problem is in AboutBox1. Show us some of that code.
I faced same problem before but I solved it by removing the statements below the InitializeComponent();
Default code:
partial class AboutBox1 : Form
{
public AboutBox1()
{
InitializeComponent();
this.Text = String.Format("About {0} {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct;
this.labelVersion.Text = String.Format("Version {0} {0}", AssemblyVersion);
this.labelCopyright.Text = AssemblyCopyright;
this.labelCompanyName.Text = AssemblyCompany;
this.textBoxDescription.Text = AssemblyDescription;
}
}
My final code:
partial class AboutBox1 : Form
{
public AboutBox1()
{
InitializeComponent();
}
}
I couldn't find the project / project name/ assembly properties.
But commenting out the lines after InitializeComponent(); worked for me.
This is how mine looks:
public frmAboutBox1()
{
InitializeComponent();
//this.Text = String.Format("About {0}", AssemblyTitle);
//this.labelMyFFEProductName.Text = AssemblyProduct;
//this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion);
//this.labelCopyright.Text = AssemblyCopyright;
//this.labelCompanyName.Text = AssemblyCompany;
//this.textBoxDescription.Text = AssemblyDescription;
}
If you are an amateur like me, to find these lines, click the AboutBox in the project explorer, and hit the View Code button <>.

.NET 2.0 WinForm print screen

I would like to print an image of a dialog, as if [alt][Print Scrn] were used. Does the framework allow for this to be done programmatically?
The Graphics.CopyFromScreen(..) method should do what you need.
Here's a good sample I found on the web:
http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html
EDIT: Code sample: (I created it as an extension method)
public static class FormExtensions
{
public static void SaveAsImage(this Form form, string fileName, ImageFormat format)
{
var image = new Bitmap(form.Width, form.Height);
using (Graphics g = Graphics.FromImage(image))
{
g.CopyFromScreen(form.Location, new Point(0, 0), form.Size);
}
image.Save(fileName, format);
}
}
can be used:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.SaveAsImage("foo.bmp", ImageFormat.Bmp);
}
}
What you could probably do is use the existing DLL that has that functionality for windows. It looks like you need to grab either some key commands or do it with a form button, and use the User32.dll. Since interop can sometimes be a big pain, I found a resource here that might help you do what you want:
http://www.cornetdesign.com/2005/04/screen-print-capture-in-c-using_08.html
If you really want just the dialog, use Control.DrawToBitmap to get a BMP image from it.

Categories

Resources