0

I am working on a WPF application which is developed using MVVM pattern. The MainWindow has several Usercontrols that open when an action is performed. However, I want to close the Usercontrol once the actions are complete and on Clicking a button. I have looked in several places, but haven't had any luck with it so far. Any help would be appreciated.

It is being pointed out that my question is a duplicate of this :

Close View from ViewModel

But it is actually not, since that thread talks about closing a Window, mine is about closing an UserControl.

Adding some code to make it clear:

This is the ItemsControl in the first UserControl which hosts the second Usercontrol:

<Grid x:Name="UserControlGrid"  Width="Auto" Height="auto" Margin="0,0,0,0">
            <ItemsControl ItemsSource="{Binding ViewsToShow}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid IsItemsHost="True" Width="auto" Height="auto"></Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </Grid>

Now to open the second UserControl , in the first UserControl ViewModel, I do this:

    private ObservableCollection<ObservableObject> viewsToShow = new ObservableCollection<ObservableObject>();
            public ObservableCollection<ObservableObject> ViewsToShow
            {
                get
                {
                    return viewsToShow;
                }
                set
                {
                    viewsToShow = value;
                    OnPropertyChanged("ViewsToShow");
                }
            }

     ViewsToShow.Add(new SecondUserControlViewModel());

Thank you

UUser
  • 59
  • 8
  • @MartinBackasch: I don't think it's a duplicate since that thread talks about closing Windows. This is about UserControls. – UUser Mar 04 '19 at 15:36
  • 2
    A `UserControl` in WPF cannot be "closed" because it cannot be "opened". A `UserControl` always requires a host where it can be displayed (a `Window`, a `Page`, a `ContentControl`, etc). What do you mean by "close a `UserControl`"? – dymanoid Mar 04 '19 at 15:40
  • what on earth is suppsed to happen when you "close" a UserControl? how do you close it? – Denis Schaf Mar 04 '19 at 15:42
  • @UUser: You are right. I only read MainWindow and read over the next sentence. – Martin Backasch Mar 04 '19 at 15:45
  • So let's say I have one UserControl which is displayed as soon as the application opens. (this is inside the MainWindow). When I click on a button in the First UserControl, A second UserControl opens up and I perform certain action in there, and then hit a button . Once I hit this button , it should close this second UserControl and go back to the first UserControl – UUser Mar 04 '19 at 15:45
  • _"A second UserControl opens up"_, how do you do this? I guess, you will set the `Visibility=Visible`. So you could hide it, by setting `Visibility=Collapsed` via a Boolean property from the viewmodel – Martin Backasch Mar 04 '19 at 15:47
  • @MartinBackasch; I have an ItemsContainer in the First UserControl. I just add the second usercontrol to this ItemsContainer and it opens up. ` ` – UUser Mar 04 '19 at 15:51
  • @Sinatr: Sorry, edited the question to add code sample. – UUser Mar 04 '19 at 15:57
  • 1
    Teach me wrong, but since you are using a `ItemsSource="{Binding ViewsToShow}"` and using `Add` from your ViewModel, you should also be able to use `Remove` – Martin Backasch Mar 04 '19 at 15:58
  • Thank you all. I actually changed the code to Hide the UserControl (by using BooleanToVisibilityConverter) instead of closing it. That is working. – UUser Mar 04 '19 at 18:31

1 Answers1

1

The answer is: you should not close your usercontrols (unless they're used as separate dialogs, and this is not your case, according to your comment above).

All changes in usercontrols visibility are about navigation. Once you logically navigate to a functionality involving another usercontrol, you have to hide old one and show new control. Usually this is done via template selection:

Two templates, one per UserControl, each associated with respective ViewModel:

<DataTemplate DataType="{x:Type ViewModels:FirstViewModel}">
    <controls:FirstControl />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:SecondViewModel}">
    <controls:SecondControl />
</DataTemplate>

Then later we declare a placeholder:

<ContentControl Content="{Binding ViewModelSelector}" />

Once ViewModelSelector property returns FirstViewModel, our placeholder will show FirstControl. If we navigate ViewModelSelector property to SecondViewModel, our placeholder would auto-replace FirstControl with SecondControl and vice versa.

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42
  • I'm doing it this exact way you have mentioned above. In that case, How do I hide the SecondControl as soon as I hit a button in the SecondControl? – UUser Mar 04 '19 at 16:11
  • Just cause a change in `ViewModelSelector` property (or how it's named in your case) so `ContentControl` would update its datatemplate accordingly. Do not tackle with usercontrols manually. – Yury Schkatula Mar 04 '19 at 16:26
  • Thank you. I actually changed the code to Hide the UserControl (by using BooleanToVisibilityConverter) instead of closing it. That is working. – UUser Mar 04 '19 at 18:30