0

I just recognized that, each time when i use MVVM and try to show a ViewModel with its View, a instance of the View will be created, although i just use the same ViewModel.

In my View is a GridView. I wrote this in the code-behind to call the event of ViewModel.

private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
    DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}

The problem with that is, if i defined some events in code-behind of the View, i will get the events more than once, because instances of the View are always be created and each instance sends the ViewModel the event.

Is there somebody, who has this problem, too. Or somebody knows the solution? Thanks a lot!

-------------------------------------------------------------

Add: I have changed my code-behind like that. It works, i got the event only once. But i am not sure, whether the other views have been disposed.

public TestView()
{
   InitializeComponent();
   IsVisibleChanged += TestView_IsVisibleChanged;
}

private void TestView_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
   if (e.NewValue.Equals(false))
   {
       MyGridView.SelectionChanged -= gridView_SelectionChanged;                
   }
   else
   {
       MyGridView.SelectionChanged += gridView_SelectionChanged;
   }
}

private void gridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
   DataContext.CallOnClick((DataContext as IHasSelectedItem<IViewModel>)?.SelectedItem);
}
9
  • you have to unsubscribe your event then subscribe it will solve your issue. Commented Nov 30, 2015 at 16:58
  • Why creating a ViewModel will create new instance of View? In MVVM pattern ViewModel doesn't know about View. So you can Create View and pass ViewModel through property of the View, in this way you can use same View for different ViewModel's Commented Nov 30, 2015 at 18:08
  • 1
    Can you edit your quesotion include the code you are using to display the View? Commented Nov 30, 2015 at 19:04
  • With the MVVM-Pattern you shouldn't have any code in your code-behind of your view. If you need something you can either write an attachedproperty or use an EventToCommand-Binding. Please show us your codebehind-code Commented Dec 1, 2015 at 7:02
  • @TomTom - MVVM pattern allow to have code-behind code. But code must contains only View's logic Commented Dec 1, 2015 at 7:03

1 Answer 1

2

The MVVM solution to your problem is to not use the IsVisibleChanged event at all. Instead of that, we simply create a bool property in the view model:

private bool isVisible = false;

public bool IsVisible
{
    get { return isVisible; }
    set { isVisible = value; NotifyPropertyChanged("IsVisible"); }
}

Now you can data bind this property to the Visibility property of the relevant control using a BooleanToVisibilityConverter:

Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"

Now whenever the Visibility property changes, the IsVisible setter will get called, so you can handle it there:

public bool IsVisible
{
    get { return isVisible; }
    set 
    {
        isVisible = value; 
        NotifyPropertyChanged("IsVisible");
        // Handle the change of visibility here... maybe call a method from here?
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I am not trying to use Visibility to control Event-Handler. I just need a way to bind my Event-Handler to View only once, and try to avoid to get the event more than once. The way with Visibility is really a trick. And i dont know, whether the instances of View have been disposed.
WPF will dispose of them when there are no longer any live references to them, so removing the event handlers should do the trick.
That means, when i remove the event handlers from Views, the others rest will be done by GC. Ok, that is the point. I had worry about that, the Views will not be really disposed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.