Is there a generic way to save user layout? - c#

I'm on a project where we use MVVM pattern.
By user layout: Sorting order of a grid, state of window or control.
For example is it possible to serialize all WPF control layout?

AvalonDock can serialize its layout, but that won't apply for grid column widths (AvalonDock is by all means great library!).
Also, I have written a set of classes that can make any property (of serializable type) of any object (in an WPF application) persistent only via adding a [Configurable] attribute to the property. It shouldn't be hard to customize it to save the properties based on a different criterion than presence of an attribute. But it saves the values on per-type basis, so it might be something else than you are looking for.
I can share if you wish.

Related

Adding controls dynamically with x:Name in MVVM

In our WPF application, we have a lot of forms with fixed fields. Every form should now be extended with fields the user can define himself. The database contains a table with these user defined fields, each with a label, a type (text, date, numeric, ...), etc.
I have found a lot of great solutions using DataTemplates, there is one issue with this however: it is not possible to generate a unique x:Name property for each field (using the field id for example).
Our application relies heavily on the x:Name property to do things as: show/hide fields, set a mask on numeric fields, move fields, ... All this functionality is read from the database, so a unique identifier per field is needed.
One solution would be to generate these fields with the x:Name in the codebehind (the Winforms way).
Another solution would be to change the functionality that uses the x:Name to using the Tag property.
Before I implement one of these solutions, I want to make sure there is no better way. Is there an MVVM way to dynamically generate fields with an x:Name?
Edit
There seems to be some confusion as to why I would need an x:Name for my fields in an MVVM scenario, so I'll clear it up with an example:
One requirement of our software is that every form field in our application can be set hidden or visible by the user. I'm talking about thousands of fields here. I could have created an property for every field that contains the visibility status and fill it from the database.
Instead, I have created an attached property (attached once in a style) that retrieves the visibility status based on the name of the field and apply it. So this functionality runs separately from the MVVM architecture (I never use the x:Name in the ViewModel). The disadvantage of using the attached property is that the form fields need an identification, being the x:Name property in my case.
Is there an MVVM way to dynamically generate fields with an x:Name
No, there isn't.
x:Name is a XAML directive that is used to uniquely identify a UI element in a XAML namescope and generate a backing field to store the value in the code-behind class of the view.
The view model doesn't and shouldn't know anything about this and it should certainly not generate such elements or backing fields as this would break everything that the MVVM pattern is all about.
If you do require to generate unique names for your UI elements for some reason, you should implement this functionality in the code-behind of the view.
MVVM is not about eliminating view-related code from the views, it is mainly about separation of concerns and testability.

Why do we need UserControl ? It seams that a Custom Control can do all the things that UserControl can do. WPF & Windows Store App [duplicate]

I've been reading some explanations about the difference between User and Custom Controls, for example this:
http://www.wpftutorial.net/CustomVsUserControl.html
I want to create, for example, a simple composition of a datagrid with 2 comboboxes which are responsible to change the values from the datagrid's items. I want to create a specific control for this because I'm going to use it a lot of times. I would like to implement the logic behind and then in the xaml invocation I only have to specify the itemsSource.
For this example should I create a User or Custom control? Since I will have properties and logic, should I have a viewmodel for this control?
EDIT: Do you know some articles with clear conceptual separation between these 2 options?
Choice is not only between user control and custom control, but among user control, custom control, customizing control template, customizing data template, header template (for collection based controls), attached properties.
Refer to Control Authoring overview
I go by following order of consideration
Attached Properties : If functionality can be achieved, I use attached properties. Example, Numeric text box.
Control Template : When requirement can be fulfilled by customizing the control template, I use this. Example, circular progress bar.
Custom control: If control template cannot do it, I use custom control. Provided I need to customize/extend already present control. Example providing Sorting, Filtering based on header row in GridView (GridView is present in metro apps, used just to illustrate the example)
User control: Least preferred one. Only when composition is required, and I am unable to do it using custom control. Like in your example, 2 Combobox, and 1 datagrid. User controls does not provide seamless lookless feature that can be leveraged through custom control or control template.
You already have some great answers that explain the differences but also understand that custom controls and UserControls have different purposes:
A UserControl typically encapusulates some sort of composite behaviour. If you have an application that needs to edit contact details in many places, for example, you could create a custom control that has the labels and text fields for all the data laid out with a submit button that has the relevant code and reuse this control throughout your application.
A custom control is a control that is derived from one of the WPF control classes (E.G. Control, ContentControl etc.) and has to be created in code.
These control usually have a single cohesive purpose (think TextBox, ComboBox, Label) rather than acting together as a whole (although this doesn't have to be the case).
UserControl's are usually easier for people unfamiliar with WPF as they can be visually designed.
My suggestion would be to start off with a UserControl. You can always refactor this into a custom control at a later date as you become more familiar with the way WPF works. Creating your control as a custom control will require knowledge of ControlTemplates and Styles as you will need to provide your own to define a look and feel for your control.
When all is said and done, as long as the control behaves correctly, it doesn't matter which approach you use.
See this post for an example of two approaches to the same problem. The post author wanted a control which can present modal content in front of the primary content. The post author actually answered his own question by implementing it as a UserControl. I have added an answer to the post which creates the control as a custom control but both have the same end effect.
If you have a view-model and you wish to create a view for it use the User-Control.
If you need an autonomous control that has no specific view-model,
you probably need a custom-control.
If you find that the functionality you need as whole, already exist in other controls you need to override an existing control template.
(i.e: for a diamond shaped button - you need to override the button control template.)
Regarding attached-properties and attached-behaviors, those are useful when you have a control which you want to extend with more properties or you want it to behave slightly different than its default behavior.
In the provided case of the composition the OP described, it can be achieved with either user control or custom control. I would prefer a custom control since there is no specific view model provided, the "input" is only a property bound to an item collection.
Oh, and, I am sorry for slightly being late.
The best explanation is in the msdn. CustomControl is more a "virtual" name, there is no class called "CustomControl" in WPF, instead its meant creating a new class building on top of one of WPF control classes, like Control, ItemsControl and even more specific Controls like TextBox or Button.
For your specific case, a UserControl should be enough, creating a CustomControl is something that can easily be avoided. While its not a bad thing, a lot of people, especially beginners in WPF coming from WinForms tend to subclass more then necessary.
If this is somehow your first time building controls, I recommend UserControl as VS lets you design its interface more easily. Custom Controls are more powerful, but you have to CLEARLY separate your control's logic from its interface and this requires a bit more preparation.
You can easily Visually design CustomControl.
Create new UserControl (or Window). Create its xaml structure visually in Designer. Copy-paste body of the resulting xaml inside ControlTemplate of your new CustomControl (Eg. in generic theme file).
If I remember right, you are also able to visually design CustomControl template directly, in Blend.
Of course you can also instance the wip CustomControl in a Window and put the Window's Designer view as new panel above the control's xaml view in VisualStudio.
Some xaml bindings from style template don't show in Designer like this though, until I rebuild.
[ Imho GUI is mainly a visual matter and should not, and doesn't need to, be created in code. ]
Well to create a Custom control you need to implement it as a User control. Your own User control is called a Custom control. It is pretty simple.
UserControl is the base class for containing your custom content :
<UserControl>
Your custom WPF content
</UserControl>
I don't totally agree with the article. However in your case you need a UserControl that you can re-use latter in your UI.

How can I use a User Control as a Diagram Node in XamDiagram?

Working with XamDiagram in the Infragistics WPF controls library, I'm looking for a way to use existing user-controls as Diagram Nodes instead of the out-of-the-box rectangles/circles/basic shapes.
If I inherit from DiagramNode, I can set the DisplayTemplate and EditTemplate properties, but would need to provide a type of System.Windows.DataTemplate. Since the user controls I want to use are fairly complex and pre-existing, I'd like to avoid creating a brand-new DataTemplate for it.
How can I use a user control as a DiagramNode?
Both the DiagramNode and DiagramConnection have DisplayTemplate and EditTemplates you can use. It is actually all very well documented here and for more questions you can check this out.

wpf data binding to enable control based on multiple criteria

I've searched around, but don't think I really found an answer. I'm trying to get a handle more on data binding and starting to see things coming together. Can you do data binding to something like "IsEnabled" based on TWO Properties, if so, how...
ex: A Window has some controls... certain controls may or may not be enabled at certain times. Some times it's as simple as when data is available (such as finding a record to edit), or when adding... I would consider this an "Editing" mode of the window. Sometimes, certain controls are only available when doing an Edit AND the user has admin permissions.
BOTH conditions need to be true for the control to be "enabled". Similarly could be applied to visibility of a control under similar conditions.
If you're using the MVVM model (which you really should if you're doing WPF development), then you're thinking about it the wrong way.
This sort of logic belongs in the ViewModel. You should have a single property on the ViewModel that represents the visiblity of the control (or controls) and have whatever logic is required (permissions, data validity, mode, etc.) in the ViewModel to determine this value. Putting the logic on the view hamstrings you and violates SOC.
The ViewModel is supposed to model your view. That is, there should (in most cases) be a 1:1 correlation between elements and concepts in your view (such as whether or not a feature is enabled or visible) and properties on your ViewModel.
You could use MultiBindings and some custom aggregate multi-value converters to achieve this declaratively. Alternatively, it may be more explicit (and therefore recommended) to place an additional property on your view model which compounds the values of the other view model properties.

How to implement a Properties window style control/system in Windows Forms?

So what I am trying to do is to have a set UI with certain controls, and I want to have some class instance to fill in the values.
For instance:
Classes that can populate the UI:
Sharpen, Blur, Smear, ... : FilterBase
So whenever the user creates an instances of the above classes, I want to automatically fetch the values based on the UI controls, by using the class instance.
The UI has items like:
.Name (TextBox)
.Amount (NumericUpDown)
.Decay (NumericUpDown)
So if the current instance is s = new Sharpen(), I want to get s.Name to fill out UI.Name.
How do I do this in the best possible way? Elegancy, clarity, performance wise, etc.
I am gonna use reflection, but how do I store the instance of the object (Sharpen, ...) and be type safe? Should I use an System.Object instead? Or T?
public partial class ParamsUI
{
T CurrentFilter (?)
...
}
Also if I use T, how will I know what to cast it to?
Is there a better way?
Since this is using Windows Forms, the most flexible option would probably be to just use the Windows Forms PropertyGrid directly.
You can do a lot of work to customize the look and feel of this. See Getting the Most Out of the .NET Framework PropertyGrid Control for details.
Edit:
If you want to have a very flexible, easy option, and WPF is an option (hosted within an ElementHost), you could consider using WPF.
With this, you could host a UserControl containing nothing but a resource dictionary and a ContentControl.
You could then make a custom XAML file for each item you want to edit, and setup a data template in the resources specifying the mapping of which user control (xaml) to use for each element you want to edit. You can then just set the element to the user control's "DataContext" in code, and it will automatically wire everything up and "just work".

Categories