вторник, 16 ноября 2010 г.

CollectionEditor: валидация уникальных элементов

PropertyGrid - очень удобная штука. Однако же, встроенные редакторы коллекций то ли недоделаны, то ли просто не предназначены по задумке для расширений. Мне потребовалось реализовать валидацию уникальных элементов коллекции в CollectionEditor, нашел вариант со StackOverflow, однако глючный и, похоже, непроверенный.

Пришлось писать свой.

Вообще, работа с CollectionEditor немного удручает. Особенно все эти ((Controls[0] as TableLayoutPanel).Controls[6] as TableLayoutPanel)... АААааа!! Но похоже, другого пути использования уже готового CollectionEditor просто нет.

Более того, пришлось использовать "фичу" события MouseDown, когда его перехват запрещает стандартный Click-эвент.

В общем, код не слишком приятный (но полезный), так что я просто приведу его, и если кому-то впоследствии пригодится, буду рад:

public class UniqueCollectionEditor : CollectionEditor
{

    public UniqueCollectionEditor(Type type)
        : base(type)
    {
    }


    protected override CollectionForm CreateCollectionForm()
    {
        CollectionForm collectionForm = base.CreateCollectionForm();

        if (collectionForm.Controls.Count > 0)
        {
            TableLayoutPanel mainPanel = collectionForm.Controls[0] as TableLayoutPanel;
            if ((mainPanel != null) && (mainPanel.Controls.Count > 7))
            {
                TableLayoutPanel buttonPanel = mainPanel.Controls[6] as TableLayoutPanel;
                if ((buttonPanel != null) && (buttonPanel.Controls.Count > 1))
                {
                    Button okayButton = buttonPanel.Controls[0] as Button;
                    if (okayButton != null)
                    {
                        okayButton.MouseDown += new MouseEventHandler(okayButton_MouseDown);
                    }
                }
            }
        }
        return collectionForm;
    }

    void okayButton_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Clicks == 1 && e.Button == MouseButtons.Left)
        {
            Button okayButton = (Button)sender;
            CollectionForm collectionForm = (CollectionForm)okayButton.Parent.Parent.Parent;
            if (!CollectionIsValid(collectionForm.EditValue as IEnumerable<MyObject>))
            {
                MessageBox.Show("Элементы должны быть уникальными! Исправьте и повторите попытку.");
            }
        }
    }

    private bool CollectionIsValid(IEnumerable<MyObject> items)
    {
        return items.Except(items.Distinct()).Count() == 0;
    }

}

Комментариев нет:

Отправить комментарий

Внимание! Реклама и прочий спам будут беспощадно удаляться.