0

(DevExpress.Simple-)Buttonを継承するカスタムクラス用に独自のDesigner-Propertyを実装したいと思います。インデックス番号の代わりに画像と名前のプレビューを備えたImageIndex-Propertyと同様に機能するはずです。

私の問題は、DropDown-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-Methodをオーバーライドする必要がありますが、最初にGetEditStyle-Methodを変更する必要があります。

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

次に、EditValue-Methodをオーバーライドしましょう。そこには私たちが利用できる多くの機会があります。例:ボタンに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なしでそれを行うことができます。2つの方法があります。難しいものと簡単な方法。難しいのは、画像リストを使用して、画像とテキストを手動で描画することです。簡単なのは、Treeviewを使用してイメージリストを提供することです。親ノードを作成し、適切な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を作成し、DropDownControl(panel)の代わりにShowDialog(form)を使用します。

于 2013-02-18T10:21:53.287 に答える