none
Habilitar componente de uma outra janela xaml RRS feed

  • Pergunta

  • Ola pessoal, tenho o seguinte problema:

    tenho uma janela principal com um MenuItem e uma outra janela de Login.

    quando inicio a aplicaçao, a tela de login aparece por cima(ou dentro) da janela principal. até ai blz!

    mas eu quero fazer o seguinte: se o login for aceito eu habilito o menuItem da janela principal, senao, continua desabilitado esse menu.

    como fazer isso? 

    parece simples mas outras tentativas q fiz foram frustradas. obrigado a todos desde já!

    sábado, 29 de março de 2014 14:59

Respostas

  • E cara desulpa aí, eu esqueci de acrescentar static na propriedade Current. Joguei no VS e compilou sem problemas aqui. O código da classe AppManager fica assim então:

    using System;
    using System.ComponentModel;
    
    namespace SGCWPF
    {
        internal class AppManager : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private bool _IsLogged;
    
            public bool IsLogged
            {
                get
                {
                    return _IsLogged;
                }
                set
                {
                    _IsLogged = value;
                    OnPropertyChanged("IsLogged");
                }
            }
    
            private AppManager() { }
    
            private static AppManager _Current;
    
            public static AppManager Current
            {
                get
                {
                    if (_Current == null) _Current = new AppManager();
                    return _Current;
                }
            }
        }
    }

    Agora as coisas devem funcionar. Desculpe-me..


    Herbert Lausmann

    • Marcado como Resposta godinis22 domingo, 30 de março de 2014 16:13
    domingo, 30 de março de 2014 15:44

Todas as Respostas

  • Olá,

    Isso é fácil, mas qual a linguagem você está utilizando, C# ou VB?


    Herbert Lausmann

    sábado, 29 de março de 2014 15:20
  • oi desculpe, estou usando c#
    sábado, 29 de março de 2014 16:21
  • Ok,

    Acho que usando um pouco do padrão Singleton seja uma das melhores formas. Adicione um arquivo de código ao seu projeto e cole o código abaixo:

    using System;
    using System.ComponentModel;
    
    namespace MeuProjeto
    {
        internal sealed class AppManager : INotifyPropertyChanged
    {
        private event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    
        private bool _IsLogged;
        
        public bool IsLogged
        {
            get
            {
                return _IsLogged;
            }
            set
            {
                _IsLogged = value;
                OnPropertyChanged("IsLogged");
            }
        }
        
        private AppManager(){ }
        
        private AppManager _Current;
        
        public AppManager Current
        {
            get
            {
                if(_Current == null) _Current = new AppManager();
                return _Current;
            }
        }
        
    }
    }


    No MenuItem que você quer que seja ativado quando o usuário fizer login adicione o seguinte:

    <!-- Adicione a linha abaixo junto as declarações de escopo -->
    xmlns:local="clr-namespace:Namespace_Do_Seu_Projeto"
    
    <!-- Abaixo a expressão binding para usar na propriedade IsEnabled do MenuItem -->
    IsEnabled="{Binding Source={x:Static local:AppManager.Current}, Path=IsLogged}"

    Aí na janela de login, quando o usuário logar você adiciona o seguinte:

    AppManager.Current.IsLogged = true;

    Então, o DataBinding vai se encarregar de fazer a ativação do menu..

    Espero ter conseguido explicar.


    Herbert Lausmann

    sábado, 29 de março de 2014 16:45
  • hebert, primeiramente obrigado por tentar me ajudar, fiz uma classe como os codigos assim postado por vc,

    fiz uma pequena mudança, pq inicialmente estava gerando um erro na aplicaçao. mas enfim, nao deu certo o que queria. abaixo segue tudo que fiz

    using System;
    using System.ComponentModel;

    namespace SGCWPF
    {
        internal sealed class AppManager : INotifyPropertyChanged
        {
            private event PropertyChangedEventHandler PropertyChanged;

            private void  OnPropertyChanged(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }

            private bool _IsLogged =false;

            public bool IsLogged
            {
                get
                {
                    return _IsLogged;
                }
                set
                {
                    _IsLogged = value;
                    OnPropertyChanged("IsLogged");
                }
            }

            public AppManager() { }

            public AppManager _Current;

            public  AppManager Current
            {
                get
                {
                    if (_Current == null) _Current = new AppManager();
                    return _Current;
                }
            }


            event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
            {
                add { throw new NotImplementedException(); }
                remove { throw new NotImplementedException(); }
            }
        }
    }// fim da classe.

    // trecho da minha tela de login.         

     private void btnEntrar_Click(object sender, RoutedEventArgs e)
            {
                ListaUsuarios = Repositorio.ObterTodos(Situacao.Ativo);

                for (int x=0; x<=ListaUsuarios.Count-1;x++)
                {
                    if (txtUsuario.Text.Equals(ListaUsuarios[x].Usuario) && pwdSenha.Password.Equals(ListaUsuarios[x].Senha))
                    {
                        AppManager app = new AppManager(); 
                        app.Current.IsLogged = false;
                        this.Close();
                        return;
                    }

                }

    // trecho do xaml da janela principal

    <Window x:Class="SGCWPF.Menu"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:SGCWPF"
            Title="Menu"  Height="300" Width="600" AllowDrop="False" AllowsTransparency="False" ResizeMode="CanResizeWithGrip" WindowStyle="ThreeDBorderWindow" Topmost="True" WindowStartupLocation="CenterOwner" WindowState="Maximized" Loaded="Window_Loaded">

     <Menu Height="30" IsEnabled="{Binding Source={x:Static local:App.Current},Path=IsLogged}" Name="menu1" Width="1024" VerticalAlignment="Top">

    enfim, eu rodo a aplicação a tela de login aparece junto com a tela principal, porem o itemmenu esta ativado independente se o login deu certo ou nao.

    espero que tenha conseguido explicar!

    olhando por ai, vc acha que esqueci ou errei em alguma coisa? mais uma vez, obrigado pela ajuda

    domingo, 30 de março de 2014 02:45
  • Opa, eu vi uns errinhos aí no seu código, aí vou corrigir. Você não precisa mexer no código da classe AppManager. Ele é daquele jeito mesmo.

    O código da classe AppManager é assim:

    using System;
    using System.ComponentModel;
    
     namespace SGCWPF
     {
         internal sealed class AppManager : INotifyPropertyChanged
         {
             private event PropertyChangedEventHandler PropertyChanged;
    
             protected void  OnPropertyChanged(string  propertyName)
             {
                 var handler = PropertyChanged;
                 if (handler != null)
                     handler(this, new PropertyChangedEventArgs(propertyName));
             }
    
             private bool _IsLogged; //Não precisa setar para false. Por padrão uma variável bool não inicializada será false.
    
             public bool IsLogged
             {
                 get
                 {
                     return _IsLogged;
                 }
                 set
                 {
                     _IsLogged = value;
                     OnPropertyChanged("IsLogged");
                 }
             }
    
             private AppManager() { } // É assim mesmo, o construtor é privado
    
             public AppManager _Current;
    
             public  AppManager Current
             {
                 get
                 {
                     if (_Current == null) _Current = new AppManager(); // A propriedade Current sempre irá retornar a mesma instância. Mas na primeira vez a instância é nula, e portanto é definida uma nova
                     return _Current;
                 }
             }
         }
     }
    

    O código do btnEntrar fica assim:

             private void btnEntrar_Click(object sender, RoutedEventArgs e)
             {
                 ListaUsuarios = Repositorio.ObterTodos(Situacao.Ativo);
    
                 for (int x = 0; x < ListaUsuarios.Count; x++)
                 {
                     if (txtUsuario.Text.Equals(ListaUsuarios[x].Usuario) && pwdSenha.Password.Equals(ListaUsuarios[x].Senha))
                     {
                         AppManager.Current.IsLogged = true; // Aqui você informa que um usuário está logado
                         this.Close();
                         return;
                     }
    
                 }

    E o XAML do Menu fica assim:

    <Menu Height="30" IsEnabled="{Binding Source={x:Static local:AppManager.Current},Path=IsLogged}" Name="menu1" Width="1024" VerticalAlignment="Top">

    Bom, veja se as modificações que eu fiz funcionam. Eu uso esse tipo de coisa com frequência, então posso te garantir que funciona que é uma beleza. Se não funcionar, provavelmente o problema está no XAML.

    Mas testa aí e dá um retorno...


    Herbert Lausmann

    domingo, 30 de março de 2014 09:56
  • Opa, eu vi uns errinhos aí no seu código, aí vou corrigir. Você não precisa mexer no código da classe AppManager. Ele é daquele jeito mesmo.

    O código da classe AppManager é assim:

    using System;
    using System.ComponentModel;
    
     namespace SGCWPF
     {
         internal sealed class AppManager : INotifyPropertyChanged
         {
             private event PropertyChangedEventHandler PropertyChanged;
    
             protected void  OnPropertyChanged(string  propertyName)
             {
                 var handler = PropertyChanged;
                 if (handler != null)
                     handler(this, new PropertyChangedEventArgs(propertyName));
             }
    
             private bool _IsLogged; //Não precisa setar para false. Por padrão uma variável bool não inicializada será false.
    
             public bool IsLogged
             {
                 get
                 {
                     return _IsLogged;
                 }
                 set
                 {
                     _IsLogged = value;
                     OnPropertyChanged("IsLogged");
                 }
             }
    
             private AppManager() { } // É assim mesmo, o construtor é privado
    
             public AppManager _Current;
    
             public  AppManager Current
             {
                 get
                 {
                     if (_Current == null) _Current = new AppManager(); // A propriedade Current sempre irá retornar a mesma instância. Mas na primeira vez a instância é nula, e portanto é definida uma nova
                     return _Current;
                 }
             }
         }
     }

    O código do btnEntrar fica assim:

             private void btnEntrar_Click(object sender, RoutedEventArgs e)
             {
                 ListaUsuarios = Repositorio.ObterTodos(Situacao.Ativo);
    
                 for (int x = 0; x < ListaUsuarios.Count; x++)
                 {
                     if (txtUsuario.Text.Equals(ListaUsuarios[x].Usuario) && pwdSenha.Password.Equals(ListaUsuarios[x].Senha))
                     {
                         AppManager.Current.IsLogged = true; // Aqui você informa que um usuário está logado
                         this.Close();
                         return;
                     }
    
                 }

    E o XAML do Menu fica assim:

    <Menu Height="30" IsEnabled="{Binding Source={x:Static local:AppManager.Current},Path=IsLogged}" Name="menu1" Width="1024" VerticalAlignment="Top">

    Bom, veja se as modificações que eu fiz funcionam. Eu uso esse tipo de coisa com frequência, então posso te garantir que funciona que é uma beleza. Se não funcionar, provavelmente o problema está no XAML.

    Mas testa aí e dá um retorno...


    Herbert Lausmann

    oi, eu tinha mudado o codigo pq gerava uns erros. por exemplo

    internal sealed class AppManager : INotifyPropertyChanged

    Error 2 'SGCWPF.AppManager' does not implement interface member

    'System.ComponentModel.INotifyPropertyChanged.PropertyChanged'. 'SGCWPF.AppManager.PropertyChanged'

    cannot implement an interface member because it is not public.

    eu nao teria que implementar a interface INotifyPropertyChanged? o que eu deveria colocar?

    //caso eu gerasse a interface, o proximo erro é na linha abaixo:

    AppManager.Current.IsLogged = true;

    As Propriedades dessa classe Parece ser privada, protegida, como chamaria eles em outra classe? desculpe a ignorancia!

    logo quando coloco . depois do Appmanager nao aparece a propriedade Current.

    IsEnabled="{Binding Source={x:Static local:AppManager.Current},Path=IsLogged}"

    o que causa outro erro na linha acima

    Type 'local:AppManager' does not contain a static member named 'Current'.

    com aquelas mudanças que fiz a aplicação rodou, mas nao funcionou o que queria rsr.

    o que poderia ser? vou continuar tentando. vlw'

    domingo, 30 de março de 2014 14:54
  • E cara desulpa aí, eu esqueci de acrescentar static na propriedade Current. Joguei no VS e compilou sem problemas aqui. O código da classe AppManager fica assim então:

    using System;
    using System.ComponentModel;
    
    namespace SGCWPF
    {
        internal class AppManager : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private bool _IsLogged;
    
            public bool IsLogged
            {
                get
                {
                    return _IsLogged;
                }
                set
                {
                    _IsLogged = value;
                    OnPropertyChanged("IsLogged");
                }
            }
    
            private AppManager() { }
    
            private static AppManager _Current;
    
            public static AppManager Current
            {
                get
                {
                    if (_Current == null) _Current = new AppManager();
                    return _Current;
                }
            }
        }
    }

    Agora as coisas devem funcionar. Desculpe-me..


    Herbert Lausmann

    • Marcado como Resposta godinis22 domingo, 30 de março de 2014 16:13
    domingo, 30 de março de 2014 15:44
  • Show, muito obrigado amigo, tu é fera! funcionou certinho. maravilha!
    domingo, 30 de março de 2014 16:14