First, please forgive (and correct!) any misconceptions - I'm brand new to anything .NET.
Me and my team are building an application in Silverlight, using the MVVM pattern. Right now, we a viewmodel for an object with various properties (e.g. its background color). The VM implements INotifyPropertyChanged so that when those properties are updated, listeners are notified.
The problem is that these are drag-and-drop objects on a canvas, and we want to run some logic every time the position on the canvas is changed. However, my understanding is that because Canvas.Left and Canvas.Top are attached properties I can't treat them the same way as I did the properties native to the object.
Is there any way to make these attached properties work with INotifyPropertyChanged? If not, what's the best way to react to changes in the Canvas.Left and Canvas.Top properties.
Thank you very much!
Two things:
(1) To keep with the MVVM pattern, I would suggest using style triggers for these attached properties and leave them out of your View Model altogether.
(2) Along those same lines, I wouldn't have your view models know about concepts like "background color" that are purely view concerns. If there is something in your business logic/VM that keys a view concern like color, you can use value converters to translate from what the view model knows about to what the view needs to do.
Related
I'm currently in the need of setting the SelectedIndex property of my TabControl when a certain event (IEventAggregator) takes place and thought about how I'd implement that.
I came up with 2 possibilities:
Use GetView() provided by ViewAware in order to access my TabControl and set the SelectedIndex to my value
Use a property in my associated ViewModel and bind this property to my TabControl's SelectedIndex property via XAML
Both options are working fine but I personally want to get this question answered since this is not the first time I'm wondering where to implement the functionality in such cases.
I know that the first option won't enable the Notify support but besides that: What would be the proper way?
Having a GetView() method to manipulate the view directly from the viewmodel completely breaks MVVM. You might as well just put all your logic in codebehind. The whole point of MVVM is to abstract away the actual view so that it is decoupled from the logic, and the app can be unit tested.
What if you change your mind about the tabs in the future and decide to show your multiple views some other way? You've now got to start editing your viewmodel to edit the new view instead of just tweaking some XAML.
And for unit testing you're going to have no way to mock out your TabControl.
I'm trying to make something like a quiz application where 3 questions will be brought up on screen at a time, allowing the user the check a radio button containing "Yes" or "No", and have an answer come up appropriately to his response. The questions will continually come from a database I'm using.
After a few attempts I've figured that using x:Name property is not a great solution, since it doesn't allow me to use a loop in order to change the questions and answers. Is there any other way to make a grid with the same types of objects in each cell, being able to access each object inside each cell of the grid in the code-behind?
Here is list of steps you need to implement,
Need to create QuestionModel, contains question properties, make sure your model inherits INotifyPropertyChanged.
Need to create ViewModel, which contains data objects, public/dependency properties
Need to bind/set data objects/properties on viewmodel constructor
Need to set your ViewModel as a DataContext of your View(.xaml) (You can create this on zammel directly and codebehind as well
Need to bind your UI objects like Question/answers/yes-no with viewmodel properties accordingly
WPF/Silverlight has their own fundamentals like Data Binding, Resources, Compiler, Dependency Properties. Above steps comprises MVVM design pattern. During each steps, please google for specific stuff.
I guess I'm a little confused as to whether properties like display range should be placed in the model (that gets inherited as a datacontext so that subcontrols can bind to it easily)or whether I should have properties be placed in the graphviewer class, and then let the components that need access to it have their own properties that they bind to the ancestor instead. Is it cleaner to bind to an ancestor control or just to bind off the model? I feel like the latter is cleaner, but then display range is pretty clearly a property of the view.
For example. I have a property AxisdivisionUnit that is needed in a scrollviewer, as well as used by a few thumbs to recalculate position on graph updates. The scrollviewer only appears when a treeview in the top level control (graphviewer) is populated. So I could either put the property axisdivisionunit on the graphviewer and bind the property to properties in the scrollviewer and thumb. Or I could have the thumb and scrollviewer bind to properties in the model (viewmodel if i were better at separating the UI out entirely.
Let me see if I can help..
First off, since you are discussing mainly the presentation of what things look like on your UI, then I do not think that the property should be in your model at all. The real question is whether it belongs in your View or ViewModel.
AxisDivisionUnit, sounds like it is only part of how the graph looks. I'm thinking that it would make more sense for that to be in the view only. If you had some properties describing the limits of your graph that were tied to business logic, then something like that may be better off in the ViewModel since you could possibly want to test that code and if you were to replace the UI you'd still want to enforce those exact same limitations.
I guess ask yourself, "If I were to replace this graph with a totally different graph and UI to display the same data, would I have to enforce this same logic?" If the answer is no, that it is just how you want to display it for this case... then it belongs in the View and you can bind a Control's property to another control's property or use triggers, behaviors, etc. to implement it in the View.
I am required to use the mvvm pattern. I know that the viewmodel should not care about the view from what I been reading. As a result I don't know how to solve this problem:
I have a dll that basically turns a textbox and listview into an autocomplete control:
SomeDll.InitAutocomplete<string>(TextBox1, ListView1, SomeObservableCollection);
anyways I don't know how to call that method from the viewmodel using the mvvm patter. if I reference the controls in the view I will be braking the rules.
I am new to MVVM pattern and my company requires me to follow it. what will be the most appropriate way of solving this problem?
I know I will be able to solve it by passing the entire view to the viewmodel as a constructor parameter but that will totaly break the mvvm pattern just because I need to reference two controls in the view.
What you're doing here is a pure view concern, so I'd recommend doing it in the view (i.e. the code-behind). The view knows about the VM and its observable collection, so why not let the code behind make this call?
(I'd also recommend seeing if you can get a non-code/XAML API for "SomeDll", but I have no idea how much control you might have over that)
There are two things that I'd point out here -
First, this is effectively all View-layer code. As such, using code behind isn't necessarily a violation of MVVM - you're not bridging that View->ViewModel layer by including some code in the code behind, if necessary.
That being said, this is often handled more elegantly in one of two ways -
You could wrap this functionality into a new control - effectively an AutoCompleteTextBox control. This would allow you to include the "textbox" and "listview" visual elements into the control template, and bind to the completion items within Xaml.
You could turn this into an attached property (or Blend behavior), which would allow you to "attach" it to a text box, and add that functionality (all within xaml). The items collection would then become a binding on the attached property (or behavior).
I'm a bit confused as to what a viewmodel's role is beyond databinding. I have a menu built in silverlight. The menu has x number of menu items which is determined at runtime. One of the features I would like to add to this is that each menuitem has a different text colour when hovered over.
Is it the role of the view to have a colour selector method or should the view handle this in it's code behind?
Normally I would keep the coloring/styling in XAML if possible - My view of the ViewModel is that it is responsible for providing all the data (ie. not graphical stuff) from the Model in a manner the View can consume.
If it was complex logic that determined the color and it was to be reused - I might be tempted to put it in the ViewModel tho.
The view model is used by the data binding process as a "safe" way to allow you to sort/filter/group the records as seen by a specific control without (necessarily) making changes to the actual bound data set (that is, unless/until you tell it to). (FMI read Bea's article here.)
I agree with Goblin here, in that the presentation aspects like color might be best kept separate in the XAML, for example in the DataTemplate used by that control.