Home > Software engineering >  Update selected Item in LisBox
Update selected Item in LisBox

Time:11-06

I want to update the listBox items after doubleClick and modifying the selectedItem in a texbox. It doesn't work.

XAML

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListBox x:Name="lstTextes" SelectedItem="{Binding SelectedText,Mode=TwoWay}" ItemsSource="{Binding ListTexts,UpdateSourceTrigger=PropertyChanged}" Grid.Column="0"  Margin="52,54,117,85"  MouseDoubleClick="lstTextes_DblClick"/>

        <Popup x:Name="popLigText" StaysOpen="False" Grid.ColumnSpan="1" Width="300" IsOpen="false">

            <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="500" Background="#F9F9F9" FontSize="11" Foreground="#0E1D31">
                <StackPanel>
                    <TextBox x:Name="TB_LigneText" HorizontalAlignment="Center" Text="{Binding Path=SelectedItem, ElementName=lstTextes, Mode=TwoWay}" Width="300" Height="30"  KeyDown="UpdateSelectedItem"/>
                </StackPanel>
            </ScrollViewer>
        </Popup>
    </Grid>
</Window>

Code vb.net

   Imports System.ComponentModel
    
    Class MainWindow
    
        Private Property datasGravures As New Gravures
    
        Sub New()
            InitializeComponent()
            Me.DataContext = datasGravures
        End Sub
    
        Private Sub UpdateSelectedItem(sender As Object, e As KeyEventArgs)
            Dim c As TextBox = sender
            If e.Key = Key.Return Then
                Me.popLigText.IsOpen = False
            End If
    
        End Sub
    
        Private Sub lstTextes_DblClick(sender As Object, e As MouseButtonEventArgs)
            Dim c As ListBox = sender
            Me.popLigText.PlacementTarget = c
            Me.popLigText.IsOpen = True
        End Sub
    End Class
    Class Gravures
    
        Implements INotifyPropertyChanged
        Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
        Private Property _ListTexts As New List(Of String)
        Private Property _selectedText As String
    
        Sub New()
            ListTexts.Add("toto")
            ListTexts.Add("titi")
        End Sub
    
        Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)
            If Not PropertyChangedEvent Is Nothing Then
                RaiseEvent PropertyChanged(Me, e)
            End If
        End Sub
    
        Public Property ListTexts As List(Of String)
            Get
                Return _ListTexts
            End Get
            Set(value As List(Of String))
                _ListTexts = value
                OnPropertyChanged(New PropertyChangedEventArgs("ListTexts"))
            End Set
        End Property
    
        Public Property SelectedText As String
            Get
                Return _selectedText
            End Get
            Set(value As String)
                _SelectedText = value
                OnPropertyChanged(New PropertyChangedEventArgs("SelectedText"))
            End Set
        End Property
    End Class

Where is the error? Thank you for your help.

the textbox is displayed with the text of the selected item. I modify it, the list(of string) ListText is modified but the textBox does not update.

CodePudding user response:

A string is an object, an element of the ListTexts collection. The ListBox.SelectedItem property contains an object. By changing the text in the TextBox you are assigning a new string to this property, i.e. a new object. The logic of the SelectedItem property checks for the presence of the assignable object in the ItemsSource collection. And if it is not there, then it does not accept it and is reset to null.
According to your explanations, you need to implement one of two options:
1) With the string received from the TextBox, first replace the string in the ListTexts collection. And only after that add this line to SelectedItem. For this, ListTexts must be an observable collection.
2) Or create an entity for the ListTexts elements. This entity will have one string property. Implement the INotifyPropertyChanged interface in the entity. And then you can bind the TextBox to the property of the entity.

<TextBox x:Name="TB_LigneText" HorizontalAlignment="Center"
         Text="{Binding Path=SelectedItem.SomeProperty, ElementName=lstTextes, Mode=TwoWay}"
         Width="300" Height="30"  KeyDown="UpdateSelectedItem"/>

CodePudding user response:

Thank you for this detailed answer. I added a class property with a String property

Class LineText

    Implements INotifyPropertyChanged
    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    Private Property _Line As String

    Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)
        If Not PropertyChangedEvent Is Nothing Then
            RaiseEvent PropertyChanged(Me, e)
        End If
    End Sub

    Public Property Line As String
        Get
            Return _Line
        End Get
        Set(value As String)
            _Line = value
            OnPropertyChanged(New PropertyChangedEventArgs("Line"))
        End Set
    End Property
End Class

I modified the ListTexts property

Public Property ListTexts As List(Of LineText)

and replaced the label with a TextBox in the interface

<ListBox x:Name="lstTextes" ItemsSource="{Binding Path=ListTexts}" Margin="133,30,267,204" Width="400" Height="200" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBox x:Name="labline" Text="{Binding Line}" Width="200"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

no longer need the popup to modify the lines of text. Thanks

  • Related