none
Problema ao alterar um propriedade RRS feed

  • Pergunta

  • Olá, estou precisando de uma ajudinha, eu tenho 2 forms: O MainWindow com um TextBox e um Button que serve para selecionar um arquivo e tenho um outro form que fiz para usar como um OpenFileDialog em que eu seleciono um arquivo que é listado em um ListBox e passo o valor para o MainForm usar na TextBox. Estou passando a informação para uma propriedade em que eu criei:

    Class MainWindow
        Implements INotifyPropertyChanged
        Private _arquivo As String
        Public Property Arquivo() As String
            Get
                Return _arquivo
            End Get
            Set(value As String)
                _arquivo = value
                OnArquivoSelecionado(_arquivo)
            End Set
        End Property
        Protected Sub OnArquivoSelecionado(ByVal objeto As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(objeto))
        End Sub
    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
     Private Sub MainWindow_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.PropertyChanged
            txt_arquivo.Text = Arquivo
        End Sub
    
    Public Class Abrir
    
    Private Sub b_selecionar_Click(sender As Object, e As RoutedEventArgs) Handles b_selecionar.Click
            Dim caminho_item As String = txt_caminho.Text + l_items.SelectedItem
            My.Windows.MainWindow.Arquivo = caminho_item
            Me.Close()
        End Sub
    <TextBox x:Name="txt_arquivo" Margin="120,0,35,0" TextWrapping="Wrap" VerticalAlignment="Top" Background="{DynamicResource Window.Background}" Foreground="{DynamicResource Window.Foreground}"/>


    O Problema é o seguinte: ele não está alterando o texto da TextBox do MainWindow.

    Eu testei o codigo usando o MsgBox em varios pontos "Public Property Arquivo", "Protected Sub OnArquivoSelecionado", "MainWindow_PropertyChanged" e em todos eles eu recebia o valor passado, porem quando vou passar esse valor para um objeto não acontesse nada.

    Eu tentei tambem passar o valor assim:

    Private Sub b_selecionar_Click(sender As Object, e As RoutedEventArgs) Handles b_selecionar.Click
            Dim caminho_item As String = txt_caminho.Text + l_items.SelectedItem
            My.Windows.MainWindow.txt_caminho.Text = caminho_item
            Me.Close()
        End Sub

    Mas tambem sem sucesso.

    segunda-feira, 6 de janeiro de 2014 20:56

Respostas

  • Mude o código da sua segunda janela para isso:

    Private _DialogResult As String
    Public Shadowns Property DialogResult As String
    Get
        Return _DialogResult
    End Get  
    Set(value As String)
        _DialogResult = value
    End Set 
    
    Public Shadowns Function ShowDialog() As String
        MyBase.ShowDialog()
        Return DialogResult
    End Function 
    
    Private Sub b_selecionar_Click(sender As Object, e As RoutedEventArgs) Handles b_selecionar.Click
            DialogResult = txt_caminho.Text + l_items.SelectedItem
            Me.Close()
    End Sub

    Ai, faça assim para chamar a janela:

    Dim Janela2 As New NomeDaWIndow
    Arquivo = Janela2.ShowDialog()
    
    Essa é forma correta de se fazer a alteração.


    Herbert Lausmann

    terça-feira, 7 de janeiro de 2014 09:59

Todas as Respostas

  • Olá,

    Irei melhorar um pouco seu código usando o poderoso sistema de DataBinding do WPF.

    O XAML do TextBox irá ficar assim:

    <TextBox x:Name="txt_arquivo" Text="{Binding Arquivo}" Margin="120,0,35,0" TextWrapping="Wrap" VerticalAlignment="Top" Background="{DynamicResource Window.Background}" Foreground="{DynamicResource Window.Foreground}"/>

    Assim você não irá precisar mudar manualmente o texto do TextBox, visto que quando a propriedade Arquivo mudar de valor essa mudança será aplicada instantaneamente ao TextBox.

    Porém, sua implementação da interface INotifyPropertyChanged está errada. Consertando, ela ficará assim:

    Class MainWindow Implements INotifyPropertyChanged Private _arquivo As String Public Property Arquivo() As String Get Return _arquivo End Get Set(value As String) _arquivo = value

    'Você deve especificar o nome da propriedade que está tendo seu valor alterado OnPropertyChanged("Arquivo") End Set End Property

    Protected Overridable Sub OnPropertyChanged(ByVal PropertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName)) End Sub Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged End Class

    Creio que fazendo essas modificações irá funcionar.


    Herbert Lausmann

    segunda-feira, 6 de janeiro de 2014 21:47
  • Se der certo, tenho uma dica para melhorar um pouco o funcionamento do seu projeto...

    Herbert Lausmann

    segunda-feira, 6 de janeiro de 2014 21:48
  • Cara eu mudei conforme voce disse mas não funciona, eu não entendo.
    segunda-feira, 6 de janeiro de 2014 21:58
  • Veja se assim funciona:

    <TextBox x:Name="txt_arquivo"
    Text="{Binding ElementName=MainWindow, Path=Arquivo}"
    Margin="120,0,35,0" TextWrapping="Wrap" VerticalAlignment="Top" Background="{DynamicResource Window.Background}" Foreground="{DynamicResource Window.Foreground}"/>


    Herbert Lausmann

    segunda-feira, 6 de janeiro de 2014 22:04
  • Me corija se eu tiver errado, se eu usar o Binding para ligar a propriedade não há a necessidade de criar um evento para isso.
    segunda-feira, 6 de janeiro de 2014 22:05
  • Exato, por isso que você faz a implementação da interface INotifyPropertyChanged. Veja que ela possui um evento. E é para isso que ele serve.

    Herbert Lausmann

    segunda-feira, 6 de janeiro de 2014 22:08
  • Nada cara sem sucesso, eu abri um novo projeto para testar e tambem não funcionou.
    segunda-feira, 6 de janeiro de 2014 22:17
  • Eu simulei seu projeto aqui. Com o XAML assim funcionou:

    <TextBox x:Name="txt_arquivo" Text="{Binding Path=Arquivo, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Margin="120,0,35,0" TextWrapping="Wrap" VerticalAlignment="Top" Background="{DynamicResource Window.Background}" Foreground="{DynamicResource Window.Foreground}"/>

    O código ficou desta forma:

    Class MainWindow
        Implements INotifyPropertyChanged
        Private _arquivo As String
        Public Property Arquivo() As String
            Get
                Return _arquivo
            End Get
            Set(value As String)
                _arquivo = value
                'Você deve especificar o nome da propriedade que está tendo seu valor alterado
                OnPropertyChanged1("Arquivo")
            End Set
        End Property
        
        Protected Overridable Sub OnPropertyChanged1(ByVal PropertyName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
        End Sub
        Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
    End Class


    Herbert Lausmann

    segunda-feira, 6 de janeiro de 2014 23:12
  • Mas ele só funciona se usar um evento na mesma janela, o que eu preciso é mudar a propriedade a partir de outra janela.
    segunda-feira, 6 de janeiro de 2014 23:45
  • Mude o código da sua segunda janela para isso:

    Private _DialogResult As String
    Public Shadowns Property DialogResult As String
    Get
        Return _DialogResult
    End Get  
    Set(value As String)
        _DialogResult = value
    End Set 
    
    Public Shadowns Function ShowDialog() As String
        MyBase.ShowDialog()
        Return DialogResult
    End Function 
    
    Private Sub b_selecionar_Click(sender As Object, e As RoutedEventArgs) Handles b_selecionar.Click
            DialogResult = txt_caminho.Text + l_items.SelectedItem
            Me.Close()
    End Sub

    Ai, faça assim para chamar a janela:

    Dim Janela2 As New NomeDaWIndow
    Arquivo = Janela2.ShowDialog()
    
    Essa é forma correta de se fazer a alteração.


    Herbert Lausmann

    terça-feira, 7 de janeiro de 2014 09:59
  • Ai sim cara, isso é outro nivel.

    Deu certo, valeu mesmo cara!!!

    terça-feira, 7 de janeiro de 2014 11:57