none
Fechar uma janela e executar um processo SEM usar event RRS feed

  • Pergunta

  • Estou usando o modelo MVVM e gostaria de salvar alguns dados em um arquivo XML quando a Janela fechar. Como posso fazer isso?
    Tenho que inserir uma trigger na janela para quando fechar ou como posso fazer?
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
    quarta-feira, 3 de fevereiro de 2010 19:52

Respostas

  • Você tem que criar um behavior: http://reedcopsey.com/2009/10/09/using-behaviors-to-allow-the-viewmodel-to-manage-view-lifetime-in-m-v-vm/

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    quarta-feira, 3 de fevereiro de 2010 19:57
  • Behaviors em WPF usam o recurso de propriedades anexadas (Attached Properties), como Canvas.Left. Com Behaviors você pde estender uma classe sem herdar dela ou mesmo conhecer seu código fonte. Veja este artigo sobre behaviors:

    http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    quinta-feira, 4 de fevereiro de 2010 15:53
  • Para isso, você faz algo como

    public static class WindowClosingBehavior
    {
            public static ICommand GetClosing(DependencyObject obj)
            {
                return (ICommand)obj.GetValue(ClosingProperty);
            }
    
            public static void SetClosing(DependencyObject obj, ICommand value)
            {
                obj.SetValue(ClosingProperty, value);
            }
    
            public static readonly DependencyProperty ClosingProperty =
                DependencyProperty.RegisterAttached("Closing", typeof(ICommand), typeof(WindowClosingBehavior), new UIPropertyMetadata(null, ClosingChanged));
    
            private static void ClosingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var element = (Window)d;
                CancelEventHandler closingHandler = (sender, ex) => ((ICommand)d.GetValue(ClosingProperty)).Execute(null);
                if (element != null)
                {
                    if ((e.NewValue != null) && (e.OldValue == null))
                        element.Closing += closingHandler;
                    else if ((e.NewValue == null) && (e.OldValue != null))
                        element.Closing -= closingHandler;
                }
    
            }
    }
    Aí na janela faz algo como

    <Window .....
      src:WindowClosingBehavior.Closing="{Binding WindowClosingCommand}" >

    WindowClosingCommand é uma propriedade do ViewModel que faz a ac'~ao quando a janela é fechada

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    sexta-feira, 5 de fevereiro de 2010 16:34
  • Não. No primeiro post, ele falou que está usando o pattern M-V-VM. Dê uma olhada em:

    http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    sexta-feira, 5 de fevereiro de 2010 17:07

Todas as Respostas

  • Você tem que criar um behavior: http://reedcopsey.com/2009/10/09/using-behaviors-to-allow-the-viewmodel-to-manage-view-lifetime-in-m-v-vm/

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    quarta-feira, 3 de fevereiro de 2010 19:57
  • Bruno, o exemplo é ótimo e mostra realmente isso funcionando mas eu gostaria de entender e criar o meu behavior, porém nem sei o que é um behavior. Você pode ajudar?

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
    quinta-feira, 4 de fevereiro de 2010 12:41
  • Behaviors em WPF usam o recurso de propriedades anexadas (Attached Properties), como Canvas.Left. Com Behaviors você pde estender uma classe sem herdar dela ou mesmo conhecer seu código fonte. Veja este artigo sobre behaviors:

    http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    quinta-feira, 4 de fevereiro de 2010 15:53
  • Obrigado Bruno, eu já vi os exemplos e até entendi a idéia mas não consigo implementar o meu de jeito nenhum. To o dia inteiro em cima disso mas não vejo como fazer ainda.

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
    quinta-feira, 4 de fevereiro de 2010 17:13
  • Para isso, você faz algo como

    public static class WindowClosingBehavior
    {
            public static ICommand GetClosing(DependencyObject obj)
            {
                return (ICommand)obj.GetValue(ClosingProperty);
            }
    
            public static void SetClosing(DependencyObject obj, ICommand value)
            {
                obj.SetValue(ClosingProperty, value);
            }
    
            public static readonly DependencyProperty ClosingProperty =
                DependencyProperty.RegisterAttached("Closing", typeof(ICommand), typeof(WindowClosingBehavior), new UIPropertyMetadata(null, ClosingChanged));
    
            private static void ClosingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var element = (Window)d;
                CancelEventHandler closingHandler = (sender, ex) => ((ICommand)d.GetValue(ClosingProperty)).Execute(null);
                if (element != null)
                {
                    if ((e.NewValue != null) && (e.OldValue == null))
                        element.Closing += closingHandler;
                    else if ((e.NewValue == null) && (e.OldValue != null))
                        element.Closing -= closingHandler;
                }
    
            }
    }
    Aí na janela faz algo como

    <Window .....
      src:WindowClosingBehavior.Closing="{Binding WindowClosingCommand}" >

    WindowClosingCommand é uma propriedade do ViewModel que faz a ac'~ao quando a janela é fechada

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    sexta-feira, 5 de fevereiro de 2010 16:34
  • Ah.... não poderia simplesmente da um override no metodo OnClose ?
    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    sexta-feira, 5 de fevereiro de 2010 16:47
    Moderador
  • Não. No primeiro post, ele falou que está usando o pattern M-V-VM. Dê uma olhada em:

    http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    Bruno
    MVP Client Development - http://msmvps.com/blogs/bsonnino
    sexta-feira, 5 de fevereiro de 2010 17:07
  • Ah ta... quando me contaram sobre MVVM eu tinha entendi que era so nao usar ligaçao entre o XAML e o CS...

    Ainda vou ler com mais calma depois sobre esse assunto... malz ae :P
    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    sexta-feira, 5 de fevereiro de 2010 17:22
    Moderador
  • Muito obrigado Bruno, salvou meu final de semana!
    Só tive que fazer umas alterações para se encaixar na minha situação mas fechou perfeito!

    Muito obrigaod mesmo e desculpe a ignorância. ta sendo difícil migrar do 2.0, VB.net e N-Tier pra 3.5 C# MVVM tudo a mesmo tempo


    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
    sábado, 6 de fevereiro de 2010 21:48