How to make UserControl dependencies required at design/compile time? - c#

I'm creating a UserControl that exposes some dependency properties, which must be populated for the control to work.
When I use the control in XAML, I can provide values for the dependency properties. But if I fail to set all values, it won't be apparent until run-time (exception will be thrown).
Is there any way for a UserControl to mark certain dependencies as required? If this were a plain C# class, I would make its dependencies as constructor parameters. But I'm not sure what's the right way to something similar in the WPF/XAML world.
We're using .NET 3.5 and VisualStudio 2008.

A possible solution would be to let the control render an error message in its visual area, that during design time hints the developer at these properties and urges him to assign values to them.
An example of such a behaviour is the Bing Maps Control, which requires its CredentialsProvider property to be set by the application programmer. As long as the CredentialsProvider isn't set, the map shows a large label in its center with an appropriate message.
In contrast to the Bing Maps Control you may consider to show such a message at design time only and during runtime throw an exception instead.

Related

Windows Universal App 8.1 Custom User Control

For the past two weeks, I have a problem which I cannot resolve. Believe me, I have been looking for answers all over the internet without finding any solution let alone hints.
I am currently working on a Windows 8.1 Universal App. I have developed a pattern lock control (control A) similar to the one known from android devices. The control is composed of 9 points which are represented by instances of a different control (control B). Control A as well as controls B have their own dependency properties. Some of which have concrete values (e.g. StrokeBrushThickness="2") while others have a value that is defined within the app resources (e.g. Brushes).
The problem I am facing is that everything works well for the Windows Phone project. However, when I reference control A inside the Windows project I receive following XAML error for the A's dependency properties that have concrete values:
Unknown error: Cannot find a resource with the given key.
If I remove the aforementioned properties from the control, the app compiles but throws a Windows.UI.Xaml.Markup.XamlParseException during runtime:
WinRT-Informationen: Failed to assign to property < PROPERTY NAME >
Moreover, I get the following XAML error for a some resources I have defined within the app, e.g.:
<Color x:Key="ColorBackground">#F4F2F4</Color>
<SolidColorBrush x:Key="AppBackgroundBrush" Color="{ThemeResource ColorBackground}"/>
I can sort of get the whole thing to work if I remove control A and place the point controls (B) directly into a grid. However, I hope to avoid this workaround as you can image control A encapsulates a lot of functionality that is needed repeatedly across the app.
I hope I have made myself clear. If not, I'll be more than happy to provide further information.
Thank you in advance!
Probably you have failed to register your dependency properties correctly.
Check the parameters you pass to DependencyProperty.Register method.
Probably you throw an exception from your property changed callback, you shouldn't do that.
P.S. It is sometimes easier to use Expression Blend to edit those XAMLs. You will spend some time learning, the tool is not targeted towards programmers; it is for designers, so the user experience is completely different. However, if you will invest some time, it is very unlikely you will ever face problems like “Cannot find a resource with the given key”.

Design time events in WPF?

I am using Autofac with my WPF project.
At design time for some controls, I set the data context of these controls to a designer-specific view model. This view model then injects some services in through its constructor.
That's all fine. But how can I manage lifetime scoping for this? Is there any way to hook up to an event and dispose my Autofac container when the design-time phase is done?
You've said in comments:
The problem is that some of my services (for instance a hotkey service) is using the RegisterHotkey API. For that service, it's important that it is unregistered when Visual Studio is done rendering my design.
In general, those should not even get registered first when your component is in DesignTime. Designtime if for previewing the layout and inspecting view modes/states, not really for testing (though it's very tempting sometimes).
When in designtime, all interactivity of the component should be disabled. VisualStudio tries to do that, you will notice that many interactivity events/triggers are not invoked or passed to your component. However, it sometimes fails badly at this, like in case of Popups (and therefore Dropdowns, Comboboxes, etc) you can sometimes force to actually open in design-time and it yields very strange/unstable/otsafe results.
This is why you shouldn't fully trust VS and the design-time mode to "just work". You probably already know well that poorly written component can, in desing-mode, try for example to connect to a database. It shouldn't happen. Usually.
I'd say, refactor that hotkey-registering bits out into some service and stub/nullify/disable it when you detect designtime mode.
I doubt they worked in designtime, but if you needed these hotkeys to flip some switches in VM on and off, or to invoke some behavior, bind that switches or behavior to a few new properties, and instead of pressing hotkeys, set them in the designer or by designtimedata to check the effect.
Just FYI - I never researched this for WPF/XAML, but for WinForms, each component could come with a special "designer" component. VisualStudio used that 'designer' component for preparing, mantaining, rendering, editing and serializing the edited component. You could actually write a designer for your custom control, and that designer could display extra windows with custom editors, and so on. Toolkits like DevExpress heavily relied on that. I'm not sure if that there is a similar framework for XAML components. I doubt it's the same, but there may be some similar concepts kept. Anyways, I wouldn't dig into this on your place, not for such things. It's not worth it unless you really want to start extending the Designer with your custom plugins.

Developing a form designer for a scripting language, how to correctly handle the custom classes

I want to develop a custom form designer for a scripting language. The controls' properties and behavior are very very similar to the windows forms controls.
I know that design such application is not an easy task and develop it from scratch is a little to advanced for me. So I googled for it and found lots of examples in c# for custom forms designers.
I picked this one to work on top of it:
https://msdn.microsoft.com/en-us/magazine/cc163634.aspx
Most of the windows controls properties won't be used, and some will be new. Let's take a button as example, I won't need many propertie like AllowDrop, Tag, etc. Some will be new, like ControllerType and BehaviorType. Others are preety much the same but with other name, like Location which will turn to be Position.
The best approach I could think of is to create a new class derived from Button and create these new properties on this class.
I managed to implement all this but now I have a problem with the PropertyGrid. Since I'm not using most base class properties, I would like to hide them on the PropertyGrid, and if possible, rename the properties that have a diferent name. I cannot control the attributes of the base class to set [Browsable(false)].
So my questions are:
1) Is this approach I'm following correct, or is there a better one?
2) Can I control the PropertyGrid behavior like what I need or do I need to develop a custom propertygrid?
3) If I can't run away from creating a custom PropertyGrid, could someone hint me on how to do this?

Visualize object properties in a WPF control

Is it possible to visualize an object (its properties along with their values) and print it out (dump it - similar to serialization) to a WPF control, such as TreeView or PropertyGrid to inspect the object?
The goal is to display the contents of any arbitary object (not only for debugging purposes).
For further clarification: I'm not looking for any debugging tools or ways to show the WPF Visual Tree. This question has only partially something to do with WPF -> WPF is only the media to display the object dump because controls may vary between WPF and WinForms.
The output should be hierarchical for nested object instances, lists etc.
I think you should take a look at Snoop
http://snoopwpf.codeplex.com/
This program will allow you to navigate the WPF tree of any running application. Debugging is not required for this tool and it's possible the tool doesn't work with debugging. Typically I use it in non-debugging scenarios to see how my WPF controls are actually laid out and what values they have for various properties
I believe what you are looking for is the System.Diagnostics.DebuggerDisplayAttribute
You mean besides the WPF Tree Visualizer? there is Mole, which is not free anymore, but very good.
Edit:
Reading your edited question. You are explicitly naming the PropertyGrid, I take it you've already tried Extended WPF Toolkit's PropertyGrid?
So you want a control that displays at runtime the fields of a class. You will find plenty of articles regarding that by looking for "Property grid". Its not directly what you want but its a start. You basically iterate via reflection over the fields of a class, and display them in a ListView/TreeView. But, and this is were the difficult part starts, determining which fields to show and which to hide, handling with very different types and primitives and allow to edit them with type conversion (like string to Rect, point, color etc) is a very complex matter.
This control might give you a good starting point.
There are various existing controls that lets you view properties as Property Grid.
http://www.codeproject.com/Articles/87715/Native-WPF-4-PropertyGrid
https://wpftoolkit.codeplex.com/wikipage?title=PropertyGrid
https://wpg.codeplex.com/
Based on complexity, License and features they present, you will have to choose one, all of them are free for sure.
I've been searching for the answer to this for months; Snoop, Spy and all the others didn't work for me, due to thread ownership violations.
Microsoft has a windows-tool that allows you to select any running UI Element and view the Element's accessibility data:
inspect.exe
https://msdn.microsoft.com/en-us/library/dd318521(VS.85).aspx
It's available in the windows Software Development Kits which need to be downloaded and installed, and located in:
C:\Program Files\x86\(win-version)\bin\(cpu-architecture)\inspect.exe

Use Dependency Properties for global properties

I am new to WPF. I have been reading a lot about WPF and dependency properties. My understanding of Dependency Properties is to bind properties to XAML (XAML being the target). I have envisioned a program in which a single configuration window would control all visual elements of the rest of the program (font, font size, colors, etc).
In my first attempt, I created a separate window that would contain all the different configuration options. This failed because I was unable to figure out how to use the dependency properties in separate XAML files.
Also, the dependency properties can only be registered in a class that implements directly or indirectly the DependecyObject class. How do I know which wpf objects implement it? It appears the window does not, but I could be wrong. My second attempt was this, to register the dependencies in the top window, so the whole visual tree would have access to it. I had exceptions being thrown and the only thing I could think of was that the window does not implement to DependencyObject. (I could be mistaken, and the visual tree thing is still sort of a mystery to me. I am learning though)
So now I'm at a loss. Is what I am attempting even possible? The whole purpose of this project was to help me learn WPF and now I'm wondering if I should lower my expectations of what I can accomplish with WPF.
Edit:
What kind of exception? What are you trying to do? Could you paste some code?
public partial class MainWindow : Window {
public Color BackColor {
get { return (Color)GetValue(BackColorProperty); }
set { SetValue(BackColorProperty, value); }
}
public static readonly DependencyProperty BackColorProperty =
DependencyProperty.Register("BackColor",typeof(Color),typeof(MainWindow),
new UIPropertyMetadata(0));
It appears that Color was causing the exception. I changed it to int and no exception was thrown. So are primitive types only able to be registered?
WPF is a framework to help you bulit really good looking apps (it includes also Printing etc.) What are you trying to do? Should it be a part of Visual Tree?
Again, this project was only meant to get me to learn WPF. My idea was to create a main UI with different pages. A configuration button would bring up a window with options to change font, fontsize, background color, etc. These changes would be applied in the main UI as the user made the changes. My issue has been how do I access those dependency properties outside of the configuration class where they were registered? How do I have one window that can have slider and combo boxes, and any other class can access those configuration settings?
Put simply, I would like that a single configuration (fonts and colors) be somehow inherited by all UIs. And that that configuration can be changed and seen by the user.
Also, the dependency properties can only be registered in a class that implements directly or indeirectly the DependecyObject class. How do I know which wpf objects implement it? It appears the window does not, but I could be wrong.
http://msdn.microsoft.com/en-us/library/system.windows.window.aspx
look at the Inheritance Hierarchy it does implement DependecyObject
My second attempt was this, to register the dependencies in the top window, so the whole visual tree would have access to it. I had exceptions being thrown and the only thing I could thing of was that the window does not implement to DependencyObject.
What kind of exception? What are you trying to do? Could you paste some code?
So now I'm at a loss. Is what I am attempting even possible? The whole purpose of this project was to help me learn wpf and now I'm wondering if I should lower my expectations of what I can accomplish with wpf.
WPF is a framework to help you bulit really good looking apps (it includes also Printing etc.) What are you trying to do? Should it be a part of Visual Tree?
We cannot tackle here the big task of learning a whole new framework and designing your whole program. That will take time. It can be daunting but stick with it.
As for your exception, the problem is that the mysterious:
UIPropertyMetadata(0)
is actually providing the default value for the dependency property and this value must match the type specified in the second argument to Register. Since 0 is an integer and your property is a Color the dependency property subsystem throws an exception. Instead you can use:
UIPropertyMetadata(new Color())
or any other color as the default.
Dependency properties are a newer design specifically created for WPF. One of the problems they solve is to create faster resolves of the property values because they don't use older, slower, techniques (Read up on why they were created).
They are hard at first, to understand, because it's not exactly clear why they are needed when there is support for the Interface named INotifyPropertyChanged. But one main reason (among others) is that if you implement a DependencyProperty correctly, you will be able to change the design time property values of that property in the property window! Now this is a very cool thing to do because you can very easily set all of your default properties that way.
Doing this for the sake of design time property editing allows you to learn a lot more about DPs and why they are used. In fact, some prefer them everywhere, as they just are not that hard to code up.
DPs are also used when creating custom controls using the "Generic" folder method. This is how Microsoft themselves create all their controls.
There are some caveats to be aware of when using them. You cannot see the design time properties of a DPs until that particular control is contained by something else. In other words a UserControl with DPs will not show those Dps in the UserControl design. They will; however, show up in the control that contains that user control.
DPs bring maximum control using Metadata, PropertyChanged callbacks, default values, and Cohersion and other techniques which give you 100% control of what they contain. The DP is the ultimate in property control.
Keep scouring the internet as there are tons of articles out there on the topic.

Categories

Resources