WPF usercontrol and external events - c#

I'm a rookie in c# and I'm working on a player with an specialized card. I've work on a usercontrol with the typical buttons stop play, pause and record. The problem is that I don't know how to create the events such that from the principal code (Window) I could manage and call the correspondent function, since from the usercontrol file I can't acces any of the items (of course defined in window) I need to make the things work, as they are not accesible.
Thanks in advance
Best regards,
Oscar

Your UserControl needs to expose appropriate properties, methods and events, so that your Window can interact with it. For example, your UserControl might declare a Paused event, so that the Window could respond when the user pauses the control; or it might declare a Play method, so that the Window can start the control playing. When you instantiate your UserControl in the Window's XAML file, give it a name, e.g.
<local:MyControl x:Name="myControl" />
You can then refer to it from code-behind, e.g.:
myControl.Paused += MyControl_Paused;
myControl.Play();
To create the required API, create public properties, methods and events on the UserControl in the code-behind class. You say you are a "rookie in C#" so I don't know how much guidance you need, but unless you need to get into WPF data binding or event routing, you can use normal C# / .NET properties, methods and events for this. Declaring properties, methods and events in C# is widely covered in MSDN and the literature. If you specifically need help working with WPF data binding or event routing, leave a comment outlining your specific difficulty and I'll update the answer.

Related

Creating Settings view in a WPF application

This question must have been solved multiple times by many people, however after several hours of research I still haven't found what I'm looking for.
What I have is a ExportSettings.settings file with a bunch of settings (bools, strings, ints, etc) and I want to create a View for them. In order to do it I've created a simple window in which I've placed standard buttons as OK, Cancel and Close and linked them to a KeyDown event to let the user accept/cancel using Enter/Escape.
I've created in XAML the needed Checkbox, TextBox, etc, for my settings. When the ExportSettingsView class starts, in its constructor I read my settings and assign the value for each control. In past I bound them directly but that unables the cancelation of changes, so I discarded it. When the user clicks OK button I assign, again, code-behind each value for each settings. If he clicks Cancel no assignment is done and the window just closes.
I would like something like EditableObject for my settings to avoid this ugly looking way of making my SettingsView.
Some of the things I'm looking for are:
Being able to put some comments in my settings would be nice (ToolTip)
Autogeneration of controls using reflection?
Avoid creating custom settings class (and the work of saving and reading everytime the application starts/shutsdown)
Break you problem up into parts to use MVVM, create your window and bind it to another class (ViewModel), this class will have properties on it that reflects the data in your settings file. this class also has to implement INotifyPropertyChanged. It can also implement EditableObject if you want, but frankly it isn't needed.
Hook you buttons up to Commands on your VeiwModel so that when the user hits save, it writes its properties to the settings file.
In this instance:
Window is your View
The new class is your ViewModel
Settings file is your Model
This will allow you to cancel changes, just dont write to your settings file when the user hits cancel.
The biggest point is that you DONT bind to your properties settings directly.
If you want auto generated fields for the view youll have to use a property grid, but with MVVM, your view is decoupled from you model so changing from things like textbox and such to a propertygrid would be easy.
When you do a search for MVVM, dont be fooled by people using a lot of terminology, MVVM is a very simple concept, it boils down to three classes, your View (xaml), View Model (what the view binds to) and Model (your data), THATS IT! good luck
I think you need something like this http://wpfdataform.codeplex.com/
And if you use ReSharper you can easily generate wrapper class for your settings
.NET already supports very nice tool for saving application and user variables. http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
It has to be saved explicitly so it might suit you very well. You can check what type the variable is and create a suitable control.

One event for several forms

I am currently faced with a trivial task but I can't think of a solution.
In order to explain the theory of how it should work ...
There is a form of authentication. http://prntscr.com/pwat5
This form fits on TabControl -> TabItem and TabControl in turn is placed on the component Grid.
Actually, on that key input is an event by clicking authenticate and change the login form to another form.
Such forms of authentication, I need more, I went for it in the following way and laid the form data to a specific component, the structure looks like this:
Grid
ListBoxItem
MyAuthForm
... //Well, actually imposed on the rest of the crap form MyAuthForm
For an identical copy of my form MyAuthForm I clone the object, and to be more precise, I clone ListBoxItem together with all its contents to the new object and thus add it to the component Grid, that is, get a new cloned object.
Grid
ListBoxItem
MyAuthForm
... //Well, actually imposed on the rest of the crap form
ListBoxItemСlone
MyAuthFormСlone
... //And so on
But the problem is that my original object carries a variety of events but the cloned object can not deliver on certain events in the original.
How is it possible to solve this problem? To clone an object somehow could refer to the events of the original object?
In general, explained as best I could, I hope most accessible outlined what I want, thank you very much for any hints and ideas, the second day I suffer with this case and so far no ideas.
ps In the manual for each cloned object, I can not create events for such forms of authentication can be more than enough, everything has to be fast, so the only option is to somehow refer to already existing events, wpf allowed for that possibility?
Perhaps since you are working with WPF, if you bind the events to commands or any other mechanism then the cloned window, given the same datacontext would target the same methods and your problem would be solved.
I hope i understood correctly.
In the past i used Caliburn with WPF and there was something called ActionMessage there that might be of use to you.
It bubbles up through datacontexts until it finds a method with the specified name or else it throws an exception. Maybe you can use this, coupled with the fact that the 2 clones share the datacontext instance to enable you to make them all point to the same authentication method.
Hope i got it right.

Not sure on class design

i originally had a main form with 2 panels, one had a graph in that i clicked on the other had the results displayed related to what you clicked.
All this code was dumped in the main form.
I tried to be a smart alec and use inheritance, so now i have a main form which has a graph objet and i have a superclass graph -> subclass specific graph heirarchy
however now when the graph is displayed in the main form, how do i get the data back to display in the other panel? The reason i ask this is now that the graph stuff is in its own heirarchy, it has no knowledge of the panel on the main form so i have no hwere to set the data when it is set
i hope someone can help
thanks
edit: i think i might just pass the control collection for the panel in to my graph class so i can add the relevant items in there
Depending on the relation between the two forms, you can use events to message data between them.
A click event handeled in the graph can raise an event with the data you need to display, which would end up on the owning form. Depending on the relationship, you either call a function on the 2nd form to display the data, or raise an event to which the 2nd form subscribed to send over the data.
[Edit]
I read Forms instead of Panels.
The main idea remains the same though. From your style of writing, it looks like you have an Objective C history. I know on the Mac, these things would be done in Interface Builder, setting bindings to make this stuff happen, but in the .NET Winforms you do these things in code (handeling events, calling methods, etc). If you like to stick more to the way it's done with Interface Builder, you might want to take a look at WPF applications; bindings work in a very similar way to how it's done on the Mac.
I would design this as an object that aggregates another object. Have a look at the way master-detail view works.

How to implement a-form-inside-a-form with runtime embedded forms switching?

I need to implement TabControl-like behaviour with manual (on event, on a button click for example) pages switching and having all pages designed and implemented as separate forms. A form to be incorporated (as a panel control) inside main form and replaced by another form as needed.
How to achieve this?
PS: The reason why I don't want to use TabControl instead is because there are going to be too many tabs - I'd prefer to present the list of them as a TreeView and instantiate on demand. The another reason comes from another project of mine - there I am going to implement plug-ins, where a panel inside main window will be provided by a class loaded dynamically and will be runtime-switchable.
I need to implement TabControl-like behaviour with manual (on event, on a button click for example) pages switching and having all pages designed and implemented as separate forms
May I ask why this is a requirement? It seems like the logical approach would be to create a set of UserControls. You can place a UserControl in a form, and you can place a UserControl in a tab. You get modularity without the headache of implementing a very odd requirement which is a use case that the API developers obviously did not think was valid. I just can't think of a good reason to take the route you have suggested.
I did similar thing once, and for that reason, I have ReplaceControl method, which I paste below:
static public void ReplaceControl(Control ToReplace, Form ReplaceWith) {
ReplaceWith.TopLevel=false;
ReplaceWith.FormBorderStyle=FormBorderStyle.None;
ReplaceWith.Show();
ReplaceWith.Anchor=ToReplace.Anchor;
ReplaceWith.Dock=ToReplace.Dock;
ReplaceWith.Font=ToReplace.Font;
ReplaceWith.Size=ToReplace.Size;
ReplaceWith.Location=ToReplace.Location;
ToReplace.Parent.Controls.Add(ReplaceWith);
ToReplace.Visible=false;
}
Only thing left to do is to create some control manually on the form, as the placeholder for your Form. Use label, for example.
You could do this with an MDIForm as the main form, and then plain-old Forms as the separate forms. Or you could encapsulate each element's functionality as a UserControl which you can then swap out on your form in code.
The advantage of encapsulating your UI elements as UserControls is that if, for whatever reason, you need them to become forms in your application, you can just drop the UserControl on a form.
Update: Since you want to use a TreeView to select what the user is looking at, you definitely want to do this as a bunch of UserControls. The layout is simple: TreeView on the left, and whichever control is active on the right.
There's no need to justify not using a TabControl - tabs are the worst UI element in history.

Why is there an OnResizeBegin for Forms, but not Controls?

A Windows Form is a type of Control, and Controls are UI elements that have a Size property along with size-related methods such as OnResize and OnSizeChanged.
But Forms also have OnResizeBegin (and OnResizeEnd), which are not found in Control. Is this omission an oversight, a prescient design decision, or something else entirely?
OnResizeBegin event is raised when form size is changed by user, not by programmaticaly changing Form properties (like Size). Most of controls can't be sized in such way, so it hasn't OnResizeBegin event.
When you add something to a base class like Control that has such a huge number of descendents, it's going to get inherited by everything whether it makes sense or not (e.g. would many programmers care that a radio button is starting to get resized?). Every method, property and event you add makes an API that much more complicated.
Now there are plenty of other examples of things in Control that don't make sense for every child (e.g. a Leave event on a Label control), but that's part of the contradictory morass that is Forms. The attached property system used in WPF is much more elegant.

Categories