Изображение кнопки через DropDown List (Дизайнер) "

Я хочу реализовать свой собственный Designer-Property для пользовательского класса, который наследует кнопку (DevExpress.Simple-). Он должен работать аналогично ImageIndex-Property с предварительным просмотром изображения и имени вместо номера индекса.

Моя проблема в том, что я не могу выбрать значение моего Drop Down-Property. Я уверен, что я должен переопределить метод в классе ImgColNamesPropertyGridEditor, но я не знаю, какой из них.

Кнопка:

public class CButton1 : DevExpress.XtraEditors.SimpleButton
{
    private CImageCollection.Names ICNames = CImageCollection.Names.none;

    [Category("Appearance")]
    [Browsable(true)]
    [DefaultValue(CImageCollection.Names.none)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Editor(typeof(ImgColNamesPropertyGridEditor), typeof(UITypeEditor))]
    public CImageCollection.Names ImageName //Names is an Enum
    {
        get { return ImageNameGetter(); }
        set { ImageNameSetter(value); }
    }

    private CImageCollection.Names ImageNameGetter()
    {
        CImageCollection imgCol = CImageCollection.Instanz;
        if (this.ImageList == imgCol.Imagecollection)//Only if we use our Collection
        {
            return imgCol.GetEnumFromIndex(this.ImageIndex);
        }
        return CImageCollection.Names.none;
    }

    private void ImageNameSetter(CImageCollection.Names value)
    {
        CImageCollection imgCol = CImageCollection.Instanz;
        if (this.ImageList == imgCol.Imagecollection)//Only if we use our Collection
        {
            ICNames = value;
            this.ImageIndex = imgCol.GetIndexFromEnum(value);
        }
    }

    public CButton1()
    {
        CImageCollection imgcol = CImageCollection.Instanz;
        this.ImageList = imgcol.Imagecollection;
    }
}

UITypeEditor:

class ImgColNamesPropertyGridEditor : UITypeEditor
{
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    {
        //Set to true to implement the PaintValue method
        return true;
    }

    public override void PaintValue(PaintValueEventArgs e)
    {
        CImageCollection col = CImageCollection.Instanz;
        string _SourceName = col.GetEnumFromIndex((int)e.Value).ToString("g");

        //Draw the corresponding image
        Bitmap newImage = (Bitmap)CButtonRes.ResourceManager.GetObject(_SourceName);
        Rectangle destRect = e.Bounds;
        newImage.MakeTransparent();
        e.Graphics.DrawImage(newImage, destRect);
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        return base.EditValue(context, provider, value);
    }
}
0

1 ответы

Чтобы решить проблему, мы должны переопределить метод EditValue, но сначала мы должны изменить метод GetEditStyle.

public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.DropDown;
    }

Теперь давайте переопределим метод EditValue. Там у нас есть много возможностей, которые мы можем использовать. Пример. Я хочу проверить, есть ли у моей Button ImageList.

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
    {

       //If it is a Button an his ImageList is empty,
       //it doesn't need a Dropdown
        if (context.Instance.GetType() == typeof(CButton))
        {
            CButton button = context.Instance as CButton;
            if (button.ImageList == null)
            {
                return value;
            }
        }

И теперь нам нужно создать собственную панель. Там мы можем сделать много классных вещей. (Позже больше) Мы отпустим эту панель вниз. (EditorService.DropDownControl (INEP);) После его закрытия мы должны вернуть выбранное значение. (return inep.EnumValue;)

        //Panel with a ImageListBox and my Enum-Items
        ImageNameEditorPanel inep = new ImageNameEditorPanel(editorService);
        inep.EnumValue = (CImageCollection.Names)value;

        editorService.DropDownControl(inep);

        return inep.EnumValue;
    }

Чтобы создать Panel, который выглядит как DropDown List, я использовал панель и Docked (Fill) DevExpress-Control (ImageListBoxControl) в ней. Но вы можете сделать это без DexEx. Есть два пути; жесткий и простой способ. Трудно использовать Imagelist и рисовать вручную изображение и текст. Легко использовать Treeview и дать ему свой Imagelist. Создайте родительские узлы и установите правильный ImageIndex. В конструкторе вы должны установить события, чтобы закрыть панель, если что-то было нажато. Конструктор:

public ImageNameEditorPanel(IWindowsFormsEditorService editorService)
    {
        InitializeComponent();
        this.EditorService = editorService;
        this.Size = new Size(Size.Width, Size.Height + 100);
        BorderStyle = BorderStyle.None;

        [...]
        imageListBoxControl1.MouseUp += new MouseEventHandler(lbMouseUp);//Set Value
        imageListBoxControl1.SelectedIndexChanged += new EventHandler(lbSelectedIndexChanged);//Close
        Controls.Add(imageListBoxControl1);// Don't forget that one! Took me an eternity to figure out...
    }

Метод:

    void lbMouseUp(object sender, MouseEventArgs e)
    {
        EditorService.CloseDropDown();
    }

Теперь все! Если вы хотите реализовать диалоговое окно, создайте «От» и используйте ShowDialog (форму) вместо DropDownControl (панель).

0
добавлено
Про Windows
Про Windows
941 участник(ов)

Microsoft Windows и всё, что с этим связано. Список интересных групп и каналов: https://github.com/goq/telegram-list

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot