Обмен объектов в массиве - C # - PullRequest
       51

Обмен объектов в массиве - C #

3 голосов
/ 01 сентября 2010

В C # у меня есть массив MenuItem.Я пытаюсь поменять местами два объекта в индексе 2 и индексе 3 массива, используя следующий код:

MenuItem Temp = Items[2];  
Items[2] = Items[3];  
Items[3] = Temp;  

Должна быть причина, по которой вторая и третья строки не работают вC #, который я, возможно, еще не понимаю.Кто-нибудь может уточнить это немного больше?Должен ли я пойти глубже и поменять каждое свойство в объектах по отдельности?

Отредактировано - Извините.Похоже, я испортил код, когда пытался почистить его для публикации.Исправлено.

Фактический код:

MenuItem TempButton = MenuItems.Items[SelectedButton.CountId];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[SelectedButton.CountId + 1];  
MenuItems.Items[SelectedButton.CountId + 1] = TempButton;  

MenuItems.Items - это массив MenuItem

Глядя на часы, которые я поместил на MenuItems.Itemsв строке 2 или 3 ничего не происходит.

В свойстве MenuItems.Items есть функции get и set, которые могут вызывать проблему ... Подробнее ...

Ответы [ 7 ]

3 голосов
/ 01 сентября 2010

У вас есть настройки от Items[2] до Temp, что для начала было Items[2], поэтому вы фактически ничего не делаете. Я не знаю, что SelectedButton.CountId должно быть.

Но если вы просто хотите поменять местами индексы 2 и 3, вы можете сделать это:

Item Temp = Items[2];
Items[2] = Items[3];
Items[3] = Temp;
1 голос
/ 01 сентября 2010

Я помню, как сталкивался с подобным источником путаницы некоторое время назад со свойством DataRow.ItemArrayЭто свойство было крайне нелогичным по той же причине, по которой свойство Items в вашем примере кажется таким странным.

Что в конечном итоге было настолько запутанным, так это то, что свойство было спроектировано так, чтобы оно было скопировано с и присваивается , как вы обычно делаете с полем типа значения (например, int, double и т. д.).То есть, чтобы изменить элемент с индексом 2, это не будет работать:

row.ItemArray[2] = "New Value";

Приведенный выше код по существу скопирует значения из строки в новый массив, возьмет эту копиюи установите значение в индексе 2 на «Новое значение», и тогда новый массив будет сразу же вне области видимости.В моей книге предполагалось работать следующим образом:

object[] items = row.ItemArray;
items[2] = "New Value";
row.ItemArray = items;

Очень нелогично, в моей книге (примечание для разработчиков библиотеки: не делаютэто ).Но похоже, что это, вероятно, проблема, стоящая за проблемой, с которой вы столкнулись в своем коде.

Другими словами, я думаю, что код обмена у вас (сейчас) правильный.Проблема заключается в том, у кого бы ни была яркая идея заставить это свойство Items вести себя так, как будто это поле значения.

1 голос
/ 01 сентября 2010

try:

Item Temp = Items[SelectedButton.CountId];   
Items[SelectedButton.CountId] = MenuItems.Items[SelectedButton.CountId+1];   
Items[SelectedButton.CountId+1] = Temp;  

Это должно поменяться местами

1 голос
/ 01 сентября 2010

Я понятия не имею, что должно быть SelectedButton.CountId, но вы помещаете Temp обратно в тот же слот, с которого он был для начала. И MenuItems.Items, кажется, совершенно отличается от предметов.

string[] items = { "one", "two", "three" };
string temp = items[1]; // temp = "two"
items[1] = items[2]; // items[1] = "three"
items[2] = temp; // items[2] = "two"

// items is now
// { "one", "three", "two" }
1 голос
/ 01 сентября 2010

Является ли SelectedButton.CountId = 2? если так, я бы попробовал это:

Item Temp = MenuItems.Items[2];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[3];  
MenuItems.Items[3] = Temp;  

Обратите внимание, что в последней строке есть 3.

Это было бы яснее:

Item Temp = MenuItems.Items[SelectedButton.CountId];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[3];  
MenuItems.Items[3] = Temp;  
0 голосов
/ 08 июля 2013

У меня была та же проблема, что и для перемещения элементов в WPF-TreeView вверх и вниз.Так как ни один из ответов не решил проблему для меня, здесь лучшее, что я смог найти.

    private void MoveLayerUp()
    {
        if(Layers.SelectedItem != null)
        {
            int index = Layers.Items.IndexOf(Layers.SelectedItem);
            if (index > 0)
            {
                var swap = Layers.Items[index - 1];
                Layers.Items.RemoveAt(index - 1);
                Layers.Items.Insert(index, swap);
            }
        }
    }

    private void MoveLayerDown()
    {
        if (Layers.SelectedItem != null)
        {
            int index = Layers.Items.IndexOf(Layers.SelectedItem);
            if (index < Layers.Items.Count-1)
            {
                var swap = Layers.Items[index + 1];
                Layers.Items.RemoveAt(index + 1);
                Layers.Items.Insert(index, swap);
            }
        }
    }

Это решает проблему назначения элементов в коллекции.Кроме того, он имеет преимущество в том, что текущий выбранный элемент никогда не трогается и остается выбранным.

0 голосов
/ 01 сентября 2010

Решил проблему. Мне кажется, я слишком усложнил проблему.

MenuItems.Items было свойством с функциями get / set, которое возвращает / устанавливает частный ArrayList.

Я создал функцию в классе для MenuItems, которая поменяла местами индексы в приватном ArrayList. (в котором использовался стандартный код подкачки, аналогичный тому, что я пробовал, и то, что все упоминали в своих ответах.)

Спасибо всем за помощь.

...