Reputation: 878
I'm currently reviewing a Wpf Mvvm project. I noticed that in some places new dialogs are beeing created using a behavior.
Lets first take a look at the code: In the view a buttons properties are set like this.
<Button Grid.Column="0"
behaviors:OpenFileClickBehavior.IsOpenFileButton="True"
behaviors:OpenFileClickBehavior.FileOpenDialogFilter="All files (*.*)|*.*" />
And then there's a static behavior class:
public static class OpenFileClickBehavior
{
public const string IsOpenFileButtonPropertyName = "IsOpenFileButton";
public static readonly DependencyProperty IsOpenFileButtonProperty = DependencyProperty.RegisterAttached(
IsOpenFileButtonPropertyName,
typeof(bool),
typeof(OpenFileClickBehavior),
new UIPropertyMetadata(false, OnIsOpenFileButtonPropertyChanged));
public static readonly DependencyProperty OpenFileDialogFilterProperty = DependencyProperty.RegisterAttached(
"OpenFileDialogFilterProperty",
typeof(String),
typeof(OpenFileClickBehavior),
new UIPropertyMetadata(String.Empty));
private static void OnIsOpenFileButtonPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs args)
{
Button button = dpo as Button;
if (button != null)
{
if ((bool)args.NewValue)
{
button.Click += ButtonClick;
}
else
{
button.Click -= ButtonClick;
}
}
}
private static void ButtonClick(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Attachment attachment = button.DataContext as Attachment;
String filter = GetFileOpenDialogFilter(button);
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = filter;
bool? dialogResult = ofd.ShowDialog();
if (dialogResult != null && dialogResult == true)
{
attachment.Path = ofd.FileName;
}
}
So the button click event is getting registered/unregistered and handled in this class.
I know mvvm suggests viewmodels shouldn't know the view and the codebehind files of a view should be empty. This solution neither has code in the codebehind of a view nor creates a view from a viewmodel. Im wondering if this approach breaks the mvvm pattern in any other way, or has any downsides.
Thank you advance
Upvotes: 1
Views: 547
Reputation: 10849
A behavior encapsulates pieces of functionality into a reusable component, which we later on can attach to an element in a view. Emphasis is on reusable. One can do the same code in codebehind or perhaps directly in XAML so it is nothing magic about a behavior. Behaviors also have the benefit of keeping the MVVM pattern intact, since we can move code from codebehind to behaviors. One example is if we want to scroll in selected item in a ListBox and the selected item is chosen from code, e g from a search function. The ViewModel don´t know that the view use a ListBox to show the list so it can not be used to scroll in the selected item. And we don´t want to put code in the codebehind, but if we use a behavior we solve this problem and creates a reusable component which can be used again.
Upvotes: 1