Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I tried Button Binding for Closing the Window with an Interface.But I couldn't figure out, why my binding is not triggering. Please help....

What I have tried:

C#
public interface IClosable
    {
        void Close();
    }

C#
In my ViewModel :-
public DelegateCommand<IClosable> CloseCommand { get; private set; } 

public MainViewModel()
{
CloseCommand = new DelegateCommand<IClosable>(CloseWindow, CanCloseWindow);
}
private bool CanCloseWindow(IClosable parameter)
        {
            return true;
        }
        private void CloseWindow(IClosable parameter)
        {
            var closable = parameter as IClosable;
            if (closable != null)
            {
                closable.Close();
            }
        }


In my View(XAML):-
My Window Name is RestWindow
HTML
<Button x:Name="btnExit" Height="30" Width="30" Content="Exit" Command="{Binding CloseCommand, Mode=OneWay}" CommandParameter="{Binding ElementName=RestWindow}" Margin="450,125,9.8,0.2"/>

DataContext:-
MainViewModel data = new MainViewModel();
btnExit.DataContext = data;
Posted
Updated 8-Jul-19 14:53pm
v2
Comments
George Swan 8-Jul-19 1:17am    
You need to indicate in the class definition of your window that the window implements ICloseable. It is not sufficient to rely on the fact that your window has a method named Close. I would place methods that extend the functionality of a window in the window’s code behind rather than in the viewmodel. Also, it’s not necessary to set the data context of controls individually. Just set the Window’s data context and the window’s controls will ‘inherit’ it.
Priya Karthish 8-Jul-19 4:56am    
Already, I have implemented the ICloseable interface in the Class definition of my Window.
Also extednign the code for the Close Method in Window(VIew) instead of ViewModel is not a correct option in MVVM(that's my thought). Any other Suggestion please...
johannesnestler 8-Jul-19 7:27am    
No George Swan is right, it doesn't brake MVVM because it's view-only tech (to call the specific close-method). I'm the architect of a large system and we use MVVM too, solved the problem like George Swan described. The "trick" ist to implement it via OnDataContextChanged like this:
void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is IRequestClose)
{
((IRequestClose)e.NewValue).RequestClose += (s, ea) =>
{
Dispatcher.Invoke(() =>
{
if (this.IsVisible)
{
this.DialogResult = ((IRequestClose)e.NewValue).DialogResult;
}
this.Close();
});
};
}
}

So you see: we look for DataContexts (ViewModels) to implement IRequestClose and attach to it's RequestClose Event. So we can "trigger" Closing from everywhere and the view knows About it's viewmodel but the viewmodels doesn't know it's view (and ist Technology independend!) - So MMVM pure is saved regarding to this…


Feel free to ask for details.
Priya Karthish 9-Jul-19 9:58am    
Thanks for your clear explanation.

1 solution

Here is a simpler way by handle the Window's Closing event that allows for canceling the event if required. ie: if there are data changes pending for example:
C#
public partial class MainWindow : Window
{
    public MainWindow()
    {
        Closing += OnClosing;
        InitializeComponent();
    }

    private void OnClosing(object sender, CancelEventArgs e)
        => e.Cancel = ((IRequestClose)DataContext).IsCancelled();
}

public interface IRequestClose
{
    bool IsCancelled();
}

Then apply the interface to the ViewModel and implement the method.
 
Share this answer
 
Comments
Priya Karthish 9-Jul-19 9:53am    
sorry for the delay. Thanks for all u r answers. Somehow I found a solution to that.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900