It looks as if there is no IsLoaded property in a UserControl object in XAML, even if the Loaded event is there.
But the MSDN page on IsLoaded tells that it should be there since UserControl derives from FrameworkElement.
So I guess it was removed in XAML (the doc is for WPF). But I can't believe they just deleted it in WinRT, they must have replaced it with something else?
So, question:
How do I gain access to the IsLoaded boolean of a UserControl in WinRT?
Of course, it is always possible to do it by hand on every user control by registering a callback on the Loaded event, but it is a pain for such a simple thing.
There is no FrameworkElement.IsLoaded in Silverlight either, and WinRT is much closer to Silverlight than it is to WPF.
As to why it was removed, I can make an educated guess based on the documentation of the WPF property:
From a newly constructed FrameworkElement, this property starts off
false, and remains true after it is set to true, even if the element
is subsequently removed from a connected logical tree by code. true
state is set by the general presentation logic when elements are
loaded into the presentation engine.
Basically, the property in WPF is sometimes wrong. A control can load (and fire its Loaded event) multiple times, and be unloaded in the meantime. The WPF IsLoaded property can says a control is loaded even when it's not really. That's... very bad.
They probably removed it rather than fixing it because of at least one of these reasons:
They didn't want to break compatibility within WPF to older versions, or have a property which acts differently in WPF vs SL / WinRT
Tracking whether something is loaded or not is difficult and easy to get wrong, and so is inherently dangerous
Querying the loaded state of a control might be bad practice / a bad idea anyway
If you really do want to implement it yourself, then at least listen to Unloaded as well as Loaded. But I think that depending on what you're trying to do, there might be a better solution.
A "Loaded" control is simply one that is in the visual tree, so you could check if there is a path between your control and the RootVisual of the application using VisualTreeHelper, but it might not be very efficient and I would still recommend handling the event. You could implement an attached property/behavior that would give you a bindable IsLoaded property if you really need it often.
There is no IsLoaded property in the Windows Runtime version of the framework. As you point out, the link you provide is not for the Windows Runtime. For that, see this MSDN link: FrameworkElement.
The Loaded event seems to be the only way to do what you are asking.
Related
new to .net coming from vba decided to rewrite a management app using vb.net and SQL Server.
Started writing the base library for my application.
I created custom controls to use in my application that would expose a Zoom function, background color for the current active control a .modified property similar to the one available in textbox and some extra other properties (SQLTableName, SQLColumnName, ...) to enable iterating through a container (form) for modified controls and Update/Insert into a SQL table via a SQLProcessClass.
Concurrently I'd like to also implement a simple undo functionality.
My first idea was to add a PrevValue variable set in the OnEnter event if the Modified property is False, exposing an OldValue property and an Undo method in the custom controls.
However I found that the TextBoxBaseClass already exposes an Undo method and that there is an UndoEngineClass available.
Unfortunately the vs helpfile does not give examples of how to use / implement that class.
Could someone explain the usage of the UndoEngine class non-textbox controls and if it is advisable to use it or rather write my own (as I first intended to do - I also found some interesting articles about undo/redo classes) but why reinvent the wheel in case .net already provides a class for it.
thks
I just upgraded from VS 2005 to VS 2012. This is a new issue that I do not understand. I am using the default "Form1" class the VS automatically creates. I added a button to open a file open dialog and when I click the button I get this error:
Current thread must be set to single thread apartment (STA) mode before OLE calls can be >made. Ensure that your Main function has STAThreadAttribute marked on it. This exception >is only raised if a debugger is attached to the process.
I have added " to Public Class Form1:
<STAThread()> Public Class Form1
But I get this...
Attribute 'STAThreadAttribute' cannot be applied to 'Form1' because the attribute is not >valid on this declaration type.
I have searched but get some info telling me that I need to set the entry point (Form1 I believe) to be Single Thread Attribute but the above code does not work.
How?
The <STAThread()> attribute cannot be added to classes like your form. It only works when it is applied to the Main function, which is the entry point of your application.
But VB.NET hides this function from you because it is rare that one needs to mess with Main in a WinForms application. It is just needed to get the plumbing set up for your app, which the compiler can manage for you. This is controlled by the "Application Framework" checkbox in the project options. If this is checked, the compiler automatically generates the Main function and the required plumbing. You can disable this option, but it makes life quite a bit harder for the average WinForms developer because you'll have to write and maintain your own Main function.
The real question here is why this is a problem at all. The compiler-generated Main function for a WinForms application is always going to have the STAThread attribute applied to it. That is just how the WinForms framework is designed to run. If that is not happening, then there is something badly wrong with your project. I would recommend scrapping it and starting over letting Visual Studio create a new WinForms project from one of the built-in templates. Everything should Just Work™.
The other option, of course, is that you're trying to display the OpenFileDialog on a separate thread (other than your main UI thread). But from your description in the question (adding a button to the form to display the dialog), it doesn't sound like this is the case. Regardless, the solution is not to do that. For example, if you're using a BackgroundWorker to do work on a non-UI thread in order to keep the UI responsive, that's great, but you'll want to do all of the UI stuff like showing an OpenFileDialog on the main UI thread before invoking the BackgroundWorker. There is a way to set a particular thread's apartment state using the SetApartmentState function, but I really don't recommend showing an OpenFileDialog on a background thread.
I have two controls. The XAML's are big and very similar. One difference is this: they contain a listbox, in one control, it's bound to {StaticResource X}, and is multiselect, the other is bound to {StaticResource Y}, and is not multiselect. The code-behinds are also very similar. How should I combine these two classes into one? I thought about creating a base class and deriving my 2 controls from it, but I have no idea how to do that with XAML. I know I could make it easier if I set the differing properties in code instead of XAML (in which case the XAML's would become identical), but let's consider that plan B. Silverlight has no StyleSelector, it seemed like a possible solution though. Maybe VisualStateManager could do it, except it sounds bad, because my problem has nothing to do with visuals, but maybe I could define 2 states anyway. Except I think SL doesn't support binding in style definitions. Tough question for a beginner like me...
You should look into creating custom controls and using AlternateContent properties. Look these up and you'll find hundreds of tutorials.
Here's a quick google search to get you started with alternate content.
So, to sum it up, I want one control which can work in somewhat different modes, or states. The mode can affect XAML properties and code logic, too.
It seems like VisualStateManager is very limited in which properties it can manipulate. But when the differences are only visual, it's the best choice.
When there are other differences in XAML, then the obvious choice is to omit those properties from XAML and set them in code, like in the ctor. A nicer way is to expose those properties as dependency properties in code, bind to those properties in the XAML of the user control, and then you can specify those properties in other XAML's where you use this user control. When your control doesn't care what's in those properties, then it's a good design choice, too. In my case, though, when setting up those differing properties should be the responsibility of the user control itself, not its parent, and I want to expose a single mode property only, it's not good.
For this case, the best way I found so far is this:
create a normal user control (XAML+code), expose the differing properties (simple, not DP's) and bind to them in XAML
make this user control abstract, and possibly some properties, too
for each different mode the control needs to support, derive a class from this base control (code only, no XAML), provide implementations for the abstract properties
instead of using the base control in other places, use one of the derived implementations
This way, you can easily specify from outside which mode you want your control to work in. The drawback is that it's not easy to change the mode, since it's not a property you need to change but the type and instance of the control.
And finally, when there are code logic differences, too, then one way is exposing a mode property, or using the abstract class method I described above. For example, a button click handler function can be abstract, too.
I have some conditionals in my InitializeComponent which affect the layout based on some variables. Unfortunately, it seems like whenever I rebuild my application, this code is reverted back to its previous state. Is this code being regenerated based on the Designer interface? Is there a way to prevent it from doing this?
Yes, InitializeComponent is completely IDE-generated; don't even try to mess with it.
If you have conditional logic wherein you want to add/remove some controls, do it in your control's constructor after the auto-generated call to InitializeComponent.
Note that if the conditional stuff will depend on features enabled/disabled at design time (e.g., if someone else is using your control and you've provided properties to affect how that control behaves which you intend to be set at design time), using the constructor won't work since the constructor will have already run by the time the user makes his/her choices from the design view; in this case, override the OnLoad method and put your logic in there (or do some variation of this, e.g., handle the Load event itself—there are plenty of ways to skin this cat).
How do you create your own custom component for vb.net 2008? I want it to simply output to a .dll, not a whole winforms app.
So, here is what I have done so far:
Made a class library project
Added a custom control object
Confused myself badly
Googled it, to no avail
How can I control the component? For example, I want my component to not have a visible design view, I want it to stay below like the stopwatch component and the notifyicon component and such, it is not something to be designed. Then, how do I edit the possible properties a user can control, and make them effect the end result? What do I place the code which powers the component on? The class library file, or something else?
Thanks for your help! I have a whole set of components I am going to create, this will get me going much faster than trial and error.
I think you may want to check some walkthrough on how to create components. Such as this one: Walkthrough: Authoring a Component with Visual Basic. Once you are done with that one, there are more walkthroughs on various related topics, such as how to use design-time support, implementing designers and so on.
OK... This is a really abbreviated example. You should start by basing yous off of an existing .net component.
Public Class MyControl
Inherits DataGridView
'...add your properties/functionality...'
End Class
Then compile the DLL, and add it as a reference to whatever project you are working on. Once added, you can add the controls in the DLL into your toolbox.
This has more instructions on how to modify a UserControl (slightly different from the one above, but it explains well. This is a general explanation.
#comments -
Yes, there, are things that will do what you want. Start with a class that inherits Form instead of DataGridView in the example I gave you, and the changes described in the links provided.
"Your properties and functionality" is whatever you want to do that the base control does not do.