Is there any way to set style for my UserControl to look like polygon, for example triangle or sth more sophisticated? I was reading that in WPF there is almost no limits when it comes to modifing graphical interface
WPF has a "lookless" approach to controls and UI. This allows the developer to strongly separate the business logic from the UI logic and also helps to lend itself to MVVM. What this means for you is that you can use a control template or style to redefine the look of your control. To name a couple of options, you can use an image, or you could use a Path element. choose whatever works best for you. Path has the benefit of being a "vector" drawing that will resize automatically-like. Here is a nice article on WPF and "lookless" controls.
Related
I am working on new WPF/MVVM project, where I see all most all controls are written for different needs, right from textbox to treeview. All are rewritten for simple need, for example, grid,stackpanel control are rewritten to add space between each item and textbox is rewritten to include label for it so that it has both label and text input are on itself.
My question : Is there any serious issue we would encounter because of this customization?
Already, I am seeing issues with aligning all controls, will i would see any more issues because of this?.
You should never create a custom or user control to add margins, a label to a TextBox, or a new ItemTemplate to a ListBox.
UserControls are for grouping frequently used combinations of controls into one reuseable control. An example may be a custom List-of-Values control that opens a dialog. This would be fine to implement as a UserControl.
Custom controls are good when a native control does not suit your needs. Say that you want to reimplement a DateTimePicker from scratch because the native one doesn't include milliseconds.
There are no serious issues as such, but you may find yourself maintaining all these controls for the next many years without there being a need to do so.
Settings Margins should be done in the View where you are using it, or on a Style in a ResourceDictionary.
This is of course only my opinion (and that of many others, I except), but if you find that the majority of your controls are 'customized' this way, you are doing it wrong.
Style and Templates rather than UserControls and custom controls.
The main issue is that you lose the ability to alter margins only in a single view. If you change your custom controls' inner paddings and margins, you will be changing all the views in your solution. If you use a style, you can always override it by defining a new style in the view, or by setting the property directly.
I need a control where user can pick only one option. Combobox is fine, radiobuttons are ok, but for some purpose I think about another crazy, but interesting solution.
There should be a slider control on a window and three possible positions of this sliding thing. I know this can be easily accomplished by setting slider's Minimum and Maximum plus TickFrequency and IsSnapToTickEnabled properties.
Now, is there a way how to add labels on left/right edge and center of slider showing user options within the slider? Or is it neccessary place labels/textblock below?
Last, though the most important thing is, how to associate integer slider positions with string options? I thought about switch, but this is wpf - there is "more wpf" solution, isn't it?
Just drag slider's rider to it's position and by binding set class string property to appropriate value.
Every control within WPF can have its visuals completely modified to suit your needs. This was/is the beauty of WPF over WinForms.
Can your slider have a TextBlock within it? Absolutely. Style as you desire and be on your way. A great article can be found via MSDN Magazine which outlines the approach to customizing WPF controls.
With regard to the integer values, use an IVauleConverter to translate the values to whatever you prefer.
I created a rough, non MVVM demo in Silverlight that drew various lines and other 2d objects on an Canvas, based on an object model.
I'm now porting the application over to MVVM (Caliburn Micro) and am now at the point where I have my objects in my ViewModel and need to draw them on the canvas in the View.
Is MVVM in this case the wrong tool for the job?
Where should I stick the 2d drawing code?
In code-behind of the View?
Let me know if you need any more info about my situation to help. Thanks!
In a situation like this, I would personally treat your Canvas as a custom, independent control.
Ideally, you'd want to make it a control (perhaps a UserControl) with a dependency property for the "objects". The user of this control would bind the objects to a collection inside their (parented control's) ViewModel, and just treat this as part of the View.
As such, it's 100% View - so the code can be implemented any way you choose. It kind of falls outside of MVVM, since it's entirely "view."
I'd like to know what the differences between an Style (for a control) and a control template are.
Best regards,
Gonzalo
A style controls the individual properties of a control. For instance, a button style can say, "For every button, use this background." A style is changing a single property on a control.
A control template is actually handling how the control displays its bound data. Instead of saying, "I want to override a control's properties," you are assembling together other smaller controls into a single control that can present different views of the bound data.
Previously in WinForms, if you wanted to write a custom list box (say that had an icon next to each item), you had to inherit from the ListView control and override the painting methods. This involved a ton of experimentation - huge pain. With WPF templates, you can use XAML to construct smaller controls together and bind them to different properties of the parent control. You are actually defining the Visual Tree for the control.
See this article for an in-depth explanation by Charles Petzold.
Imagine your control is a house.
A Style is conceptually similar to putting down a new carpet and painting the walls. The house itself is still the same but its outward appearance is different.
A ControlTemplate is the equivalent of knocking down a wall or adding a conservatory. The actual structure of the house has changed.
Use a Style when you want to change the outward appearance of the control E.G. it's background colour or the thickness of it's border.
Use a ControlTemplate when you need to change the underlying structure of the control. This is useful when you want to change the layout of certain aspects of a control. A good example is in this article which re-templates a TabControl to look like the navigator from Microsoft Outlook.
I currently need to create a visual representation of a ferry system that displays the actual ferries their position on the sea and the state of their cargo. The ferries contain trucks and the trucks contain cars. I need to display the actual trucks and their xy postion on the deck. When the ferries are loaded the postions of the trucks are updated frequently so the look animated. Also I need to display the actual cars on the trucks. Trucks, cars and ferries have some states that need to be displayed too. So I have a hierarchical structure of data that I need to visualize in a rather realistic manner.
What would be a good way to implement this kind of stuff in WPF? Should I use MVVM with one TreeView control and create a HierarchicalDataTemplates for sea, ferry, truck and car and a ControlTemplate for the TreeView? Or should I better use UserControls and compose and update them in code instead of databinding to observable collections of the ViewModel. Do you have any experience with this? How would you do this? Could you sketch out class/control setup?
I'd recommend making a "lookless" control as opposed to making user controls. Generally I use user controls as glue/container for my lookless controls. An example of a lookless control is the Button class. It contains a default style and in Blend, you can modify the style all you like. It also supports the visual state manager so you can change how the presentation looks when states change. You can think of the codebehind of a lookless control as a mini ViewModel. Here it is ok to mix some presentation stuff and your domain classes.
If you follow this same design, you could create a Ferry lookless control. This control would have a set of it's own dependency properties (possibly listening to the OnChange of the DP).
Your Ferry control may have an ObservableCollection DP called "Trucks".
Then in your Themes\generic.xaml, create a default style for your Ferry control. Your default style may have an ItemsControl with an ItemsSource={TemplateBinding Trucks}. The ItemsControl panel template, could be your own custom panel for arranging the Trucks, or maybe you use a Canvas. For the ItemsControl items template, you would have something like this:
<DataTemplate>
<mynamespace:TruckControl/>
</DataTemplate>
You Truck control, would also be a lookless control with it's own default style, and it's data context will already be set, so you can directly do the {Binding Path=xyz}. Your Truck control could also set it's Canvas.Left/Top (if you chose to use a canvas in the pervious items control..or maybe it doesn't set its position at all if you made a custom panel for it) or a render transform as to put it at the correct X,Y. You could also use the items control in the truck's template to render out the cars in the same fashion you rendered out the trucks in the ferry control. Also its possible to create states for the VisualStateManager as to make it fully Blend supportable. So if a truck goes into a "problem state" you could easily style that state in blend to make it blink red, for instance.
I know it sounds like a lot to digest, but in the end having stylable controls all supporting an MVVM model will make your life 1000000x easier.
I'd suggest studying Microsoft's silverlight toolkit to get a good idea how to do lookless controls and such. Try looking at a simple control, like the DatePicker ( http://silverlight.codeplex.com/SourceControl/changeset/view/25992# ) One caveat is ignore DatePicker.xaml file (it's just a mirror of what gets put in generic.xaml and nothing bad would happen if you just deleted it).
The things you should pay close attention to are:
1.) The attributes on the class. These help Blend know how to deal with your control.
2.) The OnApplyTemplate override. This is where you can pull out specific elements from your template. These are known as "parts" and you will see the parts tab in Blend. The attributes in #1 can define what "parts" are in the template and what type they are expected to be.
3.) The DefaultStyleKey = typeof(...) in the constructor. This tells Silverlight what default template to use in the generic.xaml
4.) Look at Themes\generic.xaml. This is a special hardcoded file location that stores all your default templates. Search for the DatePicker style and you will get the idea :)
Good luck!
I just wanted to let you know, how I actually implemented it. It turned out that it was not necessary at all, to write custom controls or UserControls for this. All I did, was writing datatemplates for the car, ship, ferry, truck etc ViewModels. For example the datatemplate for the FerryViewModel contained an ItemsControl with a ItemsPanel of type Canvas (to be able to position the trucks) and an ItemTemplate that was a DataTemplate for TruckViewModel. A very simple and fast approach.
I'd suggest having one user control handle all the drawing. Otherwise you can get lost the the hierarchy of objects. Also it makes it easier if another item was added, say people in cars, trucks and ferries.
If your model is hierarchical then you can just pass in the top level into the control, and let the control sort itself out.
MVVM works well for existing controls, but existing WPF controls only work if there's a control that's close to what you need, and with a few tweaks would work. I can't think of a standard control in WPF that's close to what you need, so it's time to write a new control.
WPF works really really well with view models. If you can keep code behind away until specifically needed then you can separate ui from data so much more easily. It will allow your ui's to be some much more upgradeable if the data model doesn't change between different display.