0
votes

In the following class, the itemssource of a listbox should bind to the Interfaces property.

public class BaseClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private const string TYPE_TITLE = "Type";

    private string  _Type;

    public string Type
    {
        get { return _Type; }
        set { _Type = value; this.NotifyPropertyChanged(PropertyChanged, TYPE_TITLE); }
    }

    public ObservableCollection<string> Interfaces { get; set; }

    public BaseClass()
    {
        Interfaces = new ObservableCollection<string>();
    }

    public void Reset()
    {
        _Type = null;
        Interfaces.Clear();
    }
}

In that list box the selected item should be able to edit as the inline edit scenario,

<DataTemplate x:Key="BaseClass_Interfaces_InlineEdit_Template">
    <TextBox Text="{Binding Mode=TwoWay, Path=., NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextChanged="TextBox_TextChanged"/>
</DataTemplate>
<DataTemplate x:Key="BaseClass_Interfaces_InlineView_Template">
    <TextBlock Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>

<Style TargetType="{x:Type ListBoxItem}" x:Key="BaseClass_Iterfaces_ItemStyle_Template">
    <Setter Property="ContentTemplate" Value="{StaticResource BaseClass_Interfaces_InlineView_Template}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource BaseClass_Interfaces_InlineEdit_Template}" />
        </Trigger>
    </Style.Triggers>
</Style>

The ListBox has a container as a parent hierarchy which its DataContext property bind to an instance of BaseClass hence the ListBox could bind to the Interfaces property.

<ListBox Grid.Row="2" Grid.ColumnSpan="2" Margin="3" ItemsSource="{Binding Interfaces, Mode=TwoWay}" SelectionMode="Single"
             ItemContainerStyle="{StaticResource ResourceKey=BaseClass_Iterfaces_ItemStyle_Template}" />
  • The list box before select any item
    The list box before select any item
  • Editing the selected item
    Editing the selected item
  • Another item select after edit and the changes doesn't affected
    Selection changed after edit

There are two problems :

  1. The TextBox should have "Path=." otherwise the "Two-way binding requires Path or XPath." exception message received.
  2. With consider the above problem, the ObservableCollection items never updated after text changed!!!!!!
1
can you upload an image of your wanted UI?Red Wei
The images of the UI added!AhmadAli

1 Answers

0
votes

I found the answer!
My wondering was about the text box which the text property changed but the changes does not propagated to the source, based on the link the binding mechanism works on the properties of sources in the other words the change of the properties monitors not the object itself.
The solution is a wrapper class around the string, i wrote this wrapper before for another primitive type (bool).

public class Wrapper<T>
{
    public T Item { get; set; }

    public Wrapper(T value = default(T))
    {
        Item = value;
    }

    public static implicit operator Wrapper<T>(T item)
    {
        return new Wrapper<T>(item);
    }

    public static implicit operator T(Wrapper<T> item)
    {
        if (null != item)
            return item.Item;

        return default(T);
    }
}

So the editing data template change as follow

<DataTemplate x:Key="BaseClass_Interfaces_InlineEdit_Template">
    <TextBox Text="{Binding Mode=TwoWay, Path=Item, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>  

And every thing work as charm!!!