New, Useful WPF Concepts for Me
This is a quick note-to-self-and-maybe-you about my latest advances in my muddy field (as your view of WPF might be smooth, green pastures).
The ViewModel and the DataTrigger
Binding the DataTrigger
with a ViewModel
property is a sure way to remove UI-specific references from ViewModel
definitions. When your ViewModel
is referencing anything in System.Windows.Media
then you might have a problem. I’m personally OK with referencing Brushes but not something like Visibility
states. In fact, there is a BooleanToVisibilityConverter
available for use in Expression Blend that strongly suggests that a ViewModel
should have Boolean properties related to Visibility
—and this relationship can be handled by the DataTrigger
.
- BooleanToVisibilityConverter.Convert() Method: “
Visibility.Visible
if value is true; otherwise,Visibility.Collapsed
.” - Christian Mosers: “A typical example is to bind a Boolean member to the
Visibility
property. Since the visibility is anenum
value that can beVisible
,Collapsed
orHidden
, you need a value converter.”### Registering ViewModel instances in a ‘Manager’/Mediator
When a popular system like Prism is slated for some future scrum iteration (deep into the future) then you have to roll your own way of allowing your ViewModel
instances to “talk” to each other. In my little, squalid world, I need ViewModel
instances to be chatty when multiple instances of the same Window
/UserControl
declaratively bound to a ViewModel
are generated.
My little, squalid solution is to make a local ViewModelManager
class—I mean “local” to respect the local namespace where the visuals live. My ViewModelManager``.Register()
static method is used in the constructors of the relevant ViewModel
classes. This ‘registration’ process features adding the ViewModel
instance to a List<ViewModelBase>
where ViewModelBase
is my base class based on some code from Josh Smith and Laurent Bugnion. This list is now a LINQ-to-objects database ready and willing for my stupid chatty tricks.
This Register()
technique by the way can be used in a “View Manager”—I need this to support non-MVVM stuff (imperative data-retrieval operations).
Duplicating Properties among ViewModel Definitions Looks like a “Base” Class Is Needed
Take this real-world scenario where I had to show a floating window containing a replica of a UserControl
instance appearing as a Panel in a parent Window. This UserControl
is made up of smaller UserControl
definitions—each with its respective ViewModel
. I can tell whether each instance of a ViewModel
is an original (from the Panel—not in the floating Window) because of the ViewModel.IsOriginal
property on all of the instances. This strongly implies that all ViewModel
classes bound to its respective UserControl
derive from a common base class.
By the way, this may be common sense but it’s important for me to note that the ‘registration’ procedure I mentioned earlier take place in the subclass—not in the common base class.
When Trapped in a Code-Behind Situation, Binding Multiple Controls of the Same Type to a Common Control Helps
How do you change the Opacity
of 23 TextBlock
elements at once without a ViewModel
? One dirty trick is to use Element binding to a ‘chosen’ element. By changing this ‘chosen’ element all of the other bound elements change. This is a poor man’s way of getting around an imperative, non-MVVM situation.