0

I have a ListBox, which ItemsSource is bound to ViewModel's ObservableCollection. Now I'm making a custom cotrol, which should manipilate ListBox items. For instance, move items up/down. I can't work with ItemsSource, because I want this control to work with variant data types, and I don't know what Type it will be. All I know about ItemsSource type - it will be IEnumerable. So I wrote code that uses IEditableCollectionView to swap adjacent items' property values. It works fine if ItemsSource is an ObservableCollection of some complex type - ObservableCollection<Customers>.

private void ItemsSwapComplex(object originalSource, object originalDestination)
{
    IEditableCollectionView items = ListBoxToManage.Items;
    Type type = originalSource.GetType();

    // Create clones of Source and Destination
    // DOES NOT WORK WITH <string>
    dynamic cloneSource = Activator.CreateInstance(type);
    dynamic cloneDestination = Activator.CreateInstance(type);

    // Copy property values from Original to Clone
    PropertiesCopyComlex(originalSource, cloneSource);
    PropertiesCopyComlex(originalDestination, cloneDestination);

    // Copy new property values to the Source item
    items.EditItem(originalSource);
    object editSource = items.CurrentEditItem;
    PropertiesCopyComlex(cloneDestination, editSource);
    items.CommitEdit();

    // Copy new property values to the Destination item
    items.EditItem(originalDestination);
    object editDestination = items.CurrentEditItem;
    PropertiesCopyComlex(cloneSource, editDestination);
    items.CommitEdit();
}

private void PropertiesCopyComlex(object originalSource, object originalDestination)
{
    foreach (var v in originalSource.GetType().GetProperties())
    {
        v.SetValue(originalDestination, v.GetValue(originalSource));
    }
}

But if ItemsSource is a collection of simple type, like ObservableCollection<string> - it throws an exception, that string doesn't have a constructor. And I dont understand how to use IEditableCollectionView to edit simple string ListBox items. This code does not affect ItemsSource at all:

IEditableCollectionView items = ListBoxToManage.Items;

items.EditItem(originalSource);
object editSource = items.CurrentEditItem;
editSource = "New string";
items.CommitEdit();

How do I use IEditableCollectionView to edit a single string item of ItemsSource?

UPDATE: this post implies that my task is not possible. Must use a wrapper for string. And for my particular task - wrapper must implement INotifyPropertyChanged, and have at least one, parameterless, constructor

Alexey Titov
  • 235
  • 2
  • 9

1 Answers1

0

How do I use IEditableCollectionView to edit a single string item of ItemsSource?

You cannot edit a System.String because it's immutable, i.e. it cannot be modified after its creation.

Why .NET String is immutable?

If you use a mutable wrapper with a string property you can indeed modify the wrapper, but you can't assume that every type T that the enumerator returns is mutable.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • OK, bu Im not trying to edit a string. Im trying to use `EditItem` and `CommitEdit` methods – Alexey Titov May 31 '19 at 14:48
  • On a `string`. Or what does *How do I use IEditableCollectionView to edit a single string item of ItemsSource?* mean? `Activator.CreateInstance` only works on types that have a default parameterless constructor, unless you know what arguments to pass it of course. – mm8 May 31 '19 at 14:49
  • That means, that Im using `IEditableCollectionView`, which provides methods to `EditItem` and `CommitEdit` - and those methods don't work. `Activator.CreateInstance` is only the first part of code. The second part doest it in a different manner – Alexey Titov May 31 '19 at 15:00
  • So what is your current issue? Please modify your question and clarify your requirements. – mm8 May 31 '19 at 15:01