通过DropDown列表(设计师)按钮图像“

时间:2013-02-07 09:08:58

标签: windows forms button devexpress

我想为继承(DevExpress.Simple-)Button的自定义类实现我自己的Designer-Property。 它应该与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);
    }
}

1 个答案:

答案 0 :(得分:0)

要解决这个问题,我们必须覆盖EditValue-Method,但首先我们必须更改GetEditStyle-Method。

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

现在让我们覆盖EditValue-Method。我们有很多机会可以使用。 示例:我想检查我的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;
            }
        }

现在我们必须创建自己的Panel。在那里,我们可以做很多很酷的东西。 (稍后)我们放下那个面板。 (editorService.DropDownControl(INEP)) 关闭后,我们应该返回选定的值。 (返回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;
    }

为了制作一个看起来像DropDown List的Panel,我在其中使用了Panel和Docked(填充)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();
    }

现在已经完成了!如果要实现Dialog,请创建一个From并使用ShowDialog(form)而不是DropDownControl(面板)。