WPF newbie so please be gentle.
Looking to rewrite an existing VFP app in C#/WPF
All forms have containers which in turn contain textboxes, labels, etc, etc.
Using this configuration allows the user to move the container and contained controls with the mouse, set up focal points within the container to enable zooming in and out of the form, etc.
So instead of adding controls directly to the WPF form, a movable container needs to be added first and the controls added to the container.
So where to begin?
You can try the AvalonDock library to see if it can satisfy your requirement.
It sounds like one of the main things you're looking for is to add drag-and-drop ability for standard WPF panels/containers. As Mash said, AvalonDock could be of use to you, especially if you're interested in docking the panels in certain positions. But I would also suggest you taking a look at options to just add dragability to standard WPF panels. This would be a lighter-weight option to get you started quickly, without having to worry about AvalonDock's constraints.
There are certainly many ways that you could implement drag-and-drop, but a very handy capability that I think is a good fit for this task is the concept of Attached "Behaviors". Attached Behaviors basically allow you to "add on" capabilities to existing WPF controls without needing to alter or extend the actual control. There are two basic types of attached behaviors. One uses WPF Attached Properties, and the other uses what is commonly referred to as "Blend" behaviors. If you just want to get started using a bahavior to solve your immediate problem, you don't necessarily need to understand all the nuances of these two approaches, but eventually you will probably find that both of these approaches have their place, so I'd suggest reading this post about them.
In particular, there is a Blend behavior called MouseDragElementBehavior that allows you to add drag-and-drop capability to WPF panels (the "e" and "d" here are xmlns namespace prefixes):
<Border Background="LightBlue" >
<e:Interaction.Behaviors>
<b:DragBehavior/>
</e:Interaction.Behaviors>
<TextBlock Text="Drag me around!" />
</Border>
In a similar vein, you mentioned zoomability, and there is another Blend behavior that may be of use for you for that as well.
Blend behaviors are very easy to add an element if you're using Expression Blend, but you can also use them with Visual Studio. To explain how to do this, see part of Laurent's post about his magnify behavior.
Related
I've thoroughly checked the custom controls topic, spent several hours looking into custom controls written by other people. I've written my own custom button, to feel it better. I've read all the google answers around the "why custom controls", "advanced custom controls examples" and such.
My question is, WHY?
Why would I (or anybody) go through 9 circles of hell to create his own custom control, when one can just adjust an existing control to his needs (using styles and templates). I actually didn't find any explanation on google, just tons of examples, mostly from people who sound even less educated than me.
I imagine there IS such need, when talking about some complicated DataGrid with, I don't know, every cell being a button or something (and still I believe I could do it with a regular DataGrid)... But I've not found anything more complex than a beautiful button. Is there nobody sharing a complicated code on the topic?
There are different levels of element customization in WPF, depending what class you extend from. Each has its own uses and is implemented differently. It is not clear from your question if you are asking about a specific type of control or about all of them in general. So, I will tell you what I think about different ones.
UIElement or FrameworkElement
Extending UIElement gives you the lowest level custom control where you have complete control over the layout and rendering. FrameworkElement is slightly higher level as it does most of the common layout stuff for you while also allowing you to override key parts of it. The main idea with these is that they do their own rendering rather than composing other elements together.
I have made a number of custom FrameworkElements over the years. One example is a ruler similar to one you might find in a program like Photoshop. It has a bunch of properties providing customization for how it is displayed as well as showing markers indicating mouse position relative to the ruler (and a number of other little optional features). I have used it in two different professional projects. I think the main benefit is that it is extremely easy to drop in and set properties/bindings on wherever desired. Build it once, use it over and over.
Control
Extending Control introduces the concept of compositing multiple elements/controls into one reusable component via control templates.
I have used this one less often, but still find it very valuable in the right circumstances. Again, the main benefit here is reusability. You create a control with properties that make sense for what you want to do, then hook up those properties to the properties of the controls in it's control template. Really, this is the same as applying a new template to an existing control, with the added feature of being able to define your own dependency properties. You also have the ability to perform custom logic in the control's code if you need to.
I may be misreading some of your text, but you seem to imply that making a custom control is considerably more difficult than making a control template for an existing control. I have found that the two are nearly identical in most cases using this approach, the only difference being whether you have a code behind you can use.
User Control
A user control is really only slightly different from a custom control practically speaking. Only, instead of defining a control template, you define the visual content directly.
This is probably the most common type of custom control. It is basically the standard method for making XAML based content in a WPF application. These can be reused like other controls, but are more suited for single use such as the content of a dialog or window or something else that is specific to a single application.
Some Other Control
You can also extend an existing control to add additional functionality to it. This way, you still get all the features the control offers and only have to implement the additional bit.
For example, I have a custom control called an AutoScrollRichTextBox that extends RichTextBox. So, it does everything a RichTextBox can do. It also has the ability to automatically scroll to the bottom when content is added to the text box (which it only does if the text box was already scrolled to the bottom before the addition content was added).
I could have implemented that feature as an attached property instead of an extension of the control (and maybe I should have), but it works, and I have used it in three different applications (as an output window and as a chat log). So, I am happy with it.
In the end, it really is just a matter of how self-contained, reusable, and easy to drop in you want a control to be. If there is already a control that does what you want, and you just want it to look different, then you should definitely use styles and templates to achieve that. However, if you want to make something that doesn't already exist, limiting yourself to using only styles and templates will make the implementation work harder and make the end result less reusable and more difficult to set up additional instances (unless all instances are identical).
The examples of making things like buttons that look different are not examples of what you should use a custom control for. They are just examples of how someone would go about making a custom control for the purpose of teaching the details of the process. If you actually want a customized button, just customize a button.
I need to show a similar-looking dialog in two different places in my application, one place as a modal dialog box and one place embedded into another menu.
From my limited understanding of WPF, it looks like Styles would allow me to write a single UserControl and customize its colors and fonts for both scenarios. However the changes are a bit more extensive, some of the element positions (for example, TextBox) are in different relative positions.
I am not sure if this can be done with Styles, or if there is a more appropriate way to do this in WPF. Worst case, I can write two completely different UserControls, but that is very bad in terms of maintainability so I'd like to avoid it.
Sure you can do it with styles/templates. Just give each of the styles a key and use the key to access the right style at the right place:
<YourUserControl Style="{StaticResource firstStyle}"/>
If you use a pattern like MVVM (I prefer MVVM Light) this is quite simple to do. You would write one ViewModel that captured all the data and behavior you wanted to expose and then create two views the way you want them, both using the same view model.
This scenario is one of the core intents behind the MVVM pattern. You're right that it is "bad" to write the behavior/plumbing twice, but the views are different, so you're not violating any re-use there.
I wanted to know which one amongst Style and UserControl would be better to use in WPF?
For example:
I have created an image button in two different ways.
One uses Style and ContentTemplate property is set.
It uses one other class with dependency properties.
The other way is I have created a UserControl which has a button and its content property is set.
The file UserControl.xaml.cs also contains the dependency properties.
For Code details see the answers of this question:
Custom button template in WPF
Which one would be better to use? In which scenario should one go for Style or UserControl or any CustomControl?
Styles are limited to setting default properties on XAML elements. For example, when I set the BorderBrush , I can specify the brush but not the width of the border. For complete freedom of a control’s appearance, use templates. To do this, create a style and specify the Template property.
Styles and templates still only allow you to change the appearance of a control. To add behavior and other features, you’ll need to create a custom control.
For example,
To create a button like a play button use styles and templates, but to create a a play button which will change its appearance after pausing it use UserControl.
For this type of thing I would go with Style, even though I'm not really adept with graphical tools. I tend to produce a basic, boring style that I can get started with and then prettify it once the application functionality has been verified.
The nicest thing about WPF is being able to distance much of the graphical look, feel and behaviour away from the code.
This allows you to change the style of your application without revisiting the code and indeed means that you can change styles on the fly at runtime.
There is an awkward line to tread with regards to how much behaviour is placed within the XAML and how much is placed within the code. A rough guide would be to decide on what behaviour must always be present within the UI and place that in the code, everything else place within the XAML.
Think of the code as being an abstract class with defined interfaces and the XAML Styles as being classes based on that class and you'll get an idea of what I mean.
Conversely, I know that people who are far more adept at the GUI work prefer to put more functionality in the XAML and others who prefer the code side, because they find the GUI work slow or difficult.
When thought of that way you'll see that there's never really a right or wrong answer, just better solutions that suit your skills.
My company's product is, at its core, a framework for developing metadata-driven UIs. I don't know how to characterize it less succinctly than that, and hope I won't need to for purposes of this question, but we'll see.
I've been trying to come up to speed on WPF, and have been building UI prototypes here and there, and recently I decided to see if I could use Expression Blend to help with the design of these UIs. And I'm pretty mystified at this point.
It appears to me as though Expresssion Blend is designed with the expectation that you already know all of the objects that are going to be present in the UI at design time. But our program generates these object dynamically at runtime.
For instance, a data row might be presented in a horizontal StackPanel containing alternating TextBlocks (for captions) and TextBoxes (for data fields). The number of these objects depends on metadata about the number of columns in the data row. I can, pretty readily, write code that runs through a metadata record and populates a StackPanel dynamically, setting up the binding of all of the controls to properties in either the data or metadata. (A TextBox's Width might be bound to metadata, while its Text is bound to data.)
But I can't even begin to figure out how to do something like this in Expression Blend. I can manually create all these controls, so that I have a set of controls that I can apply styles to and work out the visual design of the app, but it's really a pain to do this.
I can write code that goes through my data model and emits XAML for all these controls, I suppose, and then copy and paste it. But I'm going to feel really stupid if it turns out there a way to do this sort of thing in Expression Blend and I've dropped back and punted because I'm too dim to figure out the right way to think of it.
Is this enough information for someone to try formulating an answer?
I think expression blend is a very good choice ESPECIALLY if you want to design dynamic, datadriven UIs. You can use Blend to desgin DataTemplates that define how a single dataobject is to be presented to the screen. For example, if you have an object of type Person you can define the controls like textboxes, border etc. that then are to be generated automatically for each Person in your list.
You can then fill your ItemsControls (DataGrid, ListView, TreeView ...) with those dynamic databojects and WPF knows how to render them. If a Persopn is removed form the list, the generated visual item will be removed too. This is just a simple example the whole notion of dynamic data is deeply baked into WPF and you can access these features using blend.
To be able to design the datatemplates in expression blend you need to provide sample designtime data.
Also to be effective with all this it is of high advantage if you stick with the MVVM design.
Quite often when coming back to Visual Studio from Expression Blend 3, I see that Blend has helpfully added a "d:LayoutOverrides" property to my XAML. Growing up with ASP.NET designers, I naturally distrust anything I wouldn't type myself, so remove them as soon as I see them.
I know that "d:" properties are designer-only and don't impact runtime, but can anyone offer any insight into what this property does and why Blend would be so insistent that I have them all over my markup?
<Border d:LayoutOverrides="Height" />
That's just there so that Blend knows how to display your XAML in design mode. Specifically, if you've got a fluid layout that stretches to fill its container, there's no clear way for Blend to know how tall your design should be; LayoutOverrides defines that.
Those LayoutOverride settings entries are added when you (or another person running Blend) manually resizes the elements in the design surface. If you're seeing them all over your code (such as in a Border element):
You can usually delete them without any noticable affect
You might look at how you're using Blend - specifically, you should size the parent cotainer to a good size (UserControl / LayoutRoot), then set the child sizes based on fluid layout - e.g. padding and margin or * sizes
Note that Blend's ignorable attributes are stripped out at compile time and have no affect on your application's performance. So while you may want to remove them to improve code readability, they don't affect how your application runs.
d:LayoutOverrides
If a property is set to a fixed value at runtime, but you want to override it at designtime, you can use the d:LayoutOverrides attribute. All properties that should be ignored at designtime can be listed, separated by a semicolon.
(source: http://wpftutorial.net/DesigntimeVsRuntime.html)