How can you stop the expander in the list box when collapsing when data changes?

I have a screen with a list of ListBox items. An element template contains an extender control with some data in the header and some data in some of the content of the extender.

The data template for the ListBox ItemTemplate is similar to this:

<DataTemplate x:Key="MyTypeTemplate" DataType="{x:Type MyType}">
  <Expander DataContext="{Binding}">
    <Expander.Header>
      <Canvas>
        <TextBox Text="{Binding MyProperty}"/>
      </Canvas>
    </Expander.Header>
    <Canvas>
      <TextBox Text={Binding MyDetailedProperty}"/>
    </Canvas>
  </Expander>
</DataTemplate>

      

Whenever these properties changed, either "MyProperty" or "MyDetailedProperty" changed, the expander control would collapse. I believe this is because the Expander gets recreated when the data changes.

As an additional data item, the list associated with the list implements IBindingList because it comes from a library built for .NET 2.0. I am unable to recreate the list using ObservableCollection due to time constraints

0


source to share


1 answer


I ended up wrapping my model objects in a view object that adds an IsExpandable property that I could bind to the Expanded IsExpanded property and then expose the data.

This is not a universal solution, but it does solve my immediate problem. Possible issues that I see that I have not investigated have to do with whether the PropertyChanged and ListChanged event is related to memory leak issues with my UI objects, but in my situation, each object should only be created once.



Also, events outside of add and remove in change of collection are not supported, but in my case I am not firing anyone, so I cannot ignore them.

public class ExpandableItem<T> : INotifyPropertyChanged 
    where T: INotifyPropertyChanged
{
    private bool m_isExpanded;
    private readonly T m_data;

    public ExpandableItem(T data)
    {
        m_data = data;

        m_data.PropertyChanged += 
          delegate 
          { 
            PropertyChanged(this, new PropertyChangedEventArgs("Data")); 
          };
    }

    public bool IsExpanded
    {
        get { return m_isExpanded; }
        set
        {
            if (value != m_isExpanded)
            {
                m_isExpanded = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsExpanded"));
            }
        }
    }

    public T Data
    {
        get
        {
            return m_data;
        }

    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
} 

public class ExpandableList<TObject,TList> :
  ObservableCollection<ExpandableItem<TObject>>
  where TList : ObservableCollection<TObject>
  where TObject : INotifyPropertyChanged
{
    readonly TList m_list;

    public ExpandableList(TList list) 
        : base(list.Select(obj=>new ExpandableItem<TObject>(obj)))
    {
        list.CollectionChanged += OnListChanged;
        m_list = list;
    }

    public TList Data { get { return m_list; } }

    private void OnListChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            Insert(e.NewStartingIndex, e.NewItems[0]);
        }
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            RemoveAt(e.OldStartingIndex);
        }
    }
}

      

0


source







All Articles