tags:

views:

44

answers:

1

The project I am currently working on is a text editor type app. I am wondering how I can handle custom view options. eg. font family, size, bold, colors for myTextBox. My Editor Tab is a EditorTabViewModel within the View is a custom user control MarkdownEditor. Its basically a text box with some buttons for bold/italic etc. I am wondering how can I somehow set options for the custom usercontrol/editor from like a OptionsView of my app?

the way I am rendering the editor is

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:EditorTabViewModel}">
        <me:MarkdownEditor />
    </DataTemplate>
</Window.Resources>

MarkdownEditor is a user control that exposes public display properties for setting fonts, colors etc.

UPDATE: also since there can be many MarkdownEditors in the app, I want the options to be global

+2  A: 

There is nothing keeping you from having View constructs in your ViewModel... especially if you consider the ViewModel to be a model of the View (as opposed to a view of the model). Not all purists think this is a good idea. Most pragmatists, however, do.

Having properties like FontWeight, FontColor, FontSize, etc in your EditorTabViewModel would work for you here, and you can then bind them in the properties of the MarkdownEditor. It would allow for you to dynamically change the UI properties of the text via the ViewModel.

If you are a purist, and you don't like having the ViewModel know about WPF specific View constructs, you could create your own text formatting class, called something like TextFormatting. TextFormatting can include your own representation of the information you want to communicate (bold, italics, color, font size, etc). You can then bind that TextFormatting object to the MarkdownEditor using an attached property/behavior. The attached property/behavior would be responsible for mapping the formatting representation to the WPF representation.

Doing it the second way is very useful if you have different Views (WinForms/WPF) that might use the same ViewModel, since it remains view engine agnostic. It also adds a layer of complexity that the first option does not.

Brian Genisio
+1 FWIW, I'm a purist and would suggest the second approach along with some `IValueConverters` :)
Steve Greatrex
@Steve Greatrex: Yeah, that is a good idea... you can always bind View properties to your custom enums using an `IValueConverter` to map the enum to the appropriate View construct. If there become many properties to bind to, then there will have to be many value converters to do the mapping. That is where a static attached property can map a `TextFormatting` object to a `UIElement`. From there, you can create one single `IValueConverter` to do the work. This would eliminate the attached behavior (but not the attached property) component that I mentioned.
Brian Genisio
@Steve Greatrex, but what will `IValueConverters` for in this case?
jiewmeng
@jiewmeng I was suggesting that the ViewModel should not contain anything specific to WPF, which would mean that your properties should not be of types like `TextFormatting` - otherwise, if you decided to switch to WinForms you would not be able to reuse the ViewModel code. This means that you ViewModel properties would have to be of some other type (e.g. `MyTextFormatting`), and the `IValueConverter` would convert `MyTextFormatting` to the WPF-specific `TextFormatting`
Steve Greatrex
anyway, can do you know whats causing all my usercontrols to have the same text content?
jiewmeng
@jiewmeng - isn't that the content of your other question (http://stackoverflow.com/questions/4050303/wpf-can-i-have-multiple-instances-of-the-save-usercontrol-in-1-app/4050486#4050486)? I've updated my answer since your last comment...
Steve Greatrex
What possible benefit comes from keeping WPF types out of the view model? Using WPF types doesn't couple the view model to the view, and it doesn't make the view model less testable or harder to maintain - quite the opposite, as you don't have to run around implementing value converters that only exist because you've created this work for yourself.
Robert Rossney
@Robert Rossney: If you are only doing this in WPF, this becomes a purist point of view. I tend to be a bit more pragmatic and let some WPF types/enums show up. But, there are practical reasons why it might start to make sense to keep the separation. First is with re-use of the VMs in WinForms or (possibly) ASP.NET MVC. You don't want to tie the WPF types to the VM in that case. The other case is isolated (NUnit) testing in Silverlight. In that case, the testing framework cannot new up a DependancyObject. For that reason, ViewModels that include colors cannot be instantiated under test.
Brian Genisio
Interesting, thanks. My hat is off to anyone who's using view models in WinForms at all, let alone using the same view models in both WPF and WinForms.
Robert Rossney
@Robert Rossney: I have done it. You can certainly do MVVM in WinForms, and it is very nice to be able to share in that case. But it is only one of dozens of cases where I have needed to share. :)
Brian Genisio