WPF TwoWay Binding of ListBox using DataTemplate [

2019-02-25 07:12发布

问题:

Possible Duplicate:
How to make ListBox editable when bound to a List<string>?

I'm trying to set a two-binding between a List named "ListStr" object and a ListBox WPF control. Besides I want the items to be editable, so I added a DataTemplate with TextBoxes expecting that it would modify the ListStr items straight away via TextBoxes.

But when I'm attempting to edit one of them, it doesn't work...

Any Idea ?

PS: I've tried to add the Mode=TwoWay parameter, but it's still not working

Here is the XAML :

<ListBox ItemsSource="{Binding Path=ListStr}" Style="{DynamicResource ResourceKey=stlItemTextContentListBoxEdit}" />

Here is the style code :

<Style x:Key="stlItemTextContentListBoxEdit" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="#FF0F2592" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Height" Value="150" />
<Setter Property="Width" Value="200" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="ItemTemplate" Value="{DynamicResource ResourceKey=dtplItemTextContentListBoxEdit}" /></Style>

And the DataTemplate:

<DataTemplate x:Key="dtplItemTextContentListBoxEdit">
    <TextBox Text="{Binding Path=.}" Width="175" />
</DataTemplate>

回答1:

Two way binding does not work when you use {Binding Path=.} (which is long for {Binding}). Keep in mind what is happening.

The ListBox is given a list of objects, which it then creates one ListBoxItem for each item. The DataContext of the ListBoxItem is then set to that object. When you use {Binding}, you are saying to just use the object in the DataContext. When you type in the TextBox, what would it update? It can't set the DataContext and it has no idea where the object came from (so it can't update your list/array).

Where two way binding does work, is when you bind to a property on that object. But not when you bind to the object itself.



回答2:

    public class ViewModel
{
    ObservableCollection<TextItem> _listStr = new ObservableCollection<TextItem> { new TextItem("a"), new TextItem("b"), new TextItem("c") };

    public ObservableCollection<TextItem> ListStr
    {
        get  { return _listStr; }  // Add observable and propertyChanged here also if needed
    }
}

public class TextItem : NotificationObject // (NotificationObject from Prism you can just implement INotifyPropertyChanged)
{
    public TextItem(string text)
    {
        Text = text;
    }

    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            if (_text != value)
            {
                _text = value;
                RaisePropertyChanged(() => Text);
            }
        }
    }
}


xaml:

 <DataTemplate>
    <TextBox Text="{Binding Text}" Width="175" />
 </DataTemplate>