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