0

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

1 回答 1

0

为了解决这个问题,我们必须重写 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);) 关闭后,我们应该返回选择的值。(返回 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;
    }

为了制作一个看起来像下拉列表的面板,我使用了一个面板并在其中停靠(填充)了一个 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();
    }

现在完成了!如果要实现对话框,请创建一个 From 并使用 ShowDialog(form) 而不是 DropDownControl(panel)。

于 2013-02-18T10:21:53.287 回答