Usuário com melhor resposta
Habilitar componente de uma outra janela xaml

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á!
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
Todas as Respostas
-
-
-
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
-
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
-
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
-
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'
-
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
-