方法 : オーナー描画リスト ボックスを作成します。

[このドキュメントはプレビュー版であり、後のリリースで変更されることがあります。 空白のトピックは、プレースホルダーとして挿入されています。]

作成できますが、オーナー描画リスト ボックス、.NET Compact Framework として簡単に .NET Framework と同様です。 他の図面メンバーですがリスト ボックスと、他のコントロールの機能をプログラムできますを .NET Compact Framework、DrawModeDrawItem をサポートしていません。 この例は、オーナー描画リスト ボックスを作成するカスタム コントロール クラスを提供し、フォントを選択するリスト ボックスとしてコントロールを実装します。

このサンプルには、基本クラス、OwnerDrawnListBoxFontListBox の派生元が含まれています。 OwnerDrawnListBox コア関数は次のとおりです。

  • 項目、およびリスト ボックスを構築するビットマップを含む、垂直スクロール バー、配列提供します。

  • アイテムの高さのプロパティを示し、コントロールの高さの指定項目の数を描画できるかを決定します。

  • 現在のスクロール バー、項目の高さ、およびマウス ポインターの座標値で選択した項目を決定する SelectedIndex プロパティ、用意されています。

  • SelectedIndexChanged イベントを提供します。

  • アイテムの可視性を確実にします。

  • 不要な場合、スクロール バーを削除します。

  • ナビゲーション キーを押し、上向きとは、キーボード操作を提供します。

FontListBox クラスは、OwnerDrawnListBox を継承します。 実装および手法の次をとおり

  • 適切な項目の高さを決定します。

  • オーバーライド OnPaint メソッドを使用して描画として強調表示されている、選択した項目に、アイテムを描画します。 ちらつきを回避するのにこのメソッドは、すべてのグラフィック機能が描画されるまで表示しません、制御します。

  • 選択されているフォントの名前を含む、SelectedFaceName プロパティを提供します。

DrawFontList をフォームは、次の処理を行います。

  • FontListBox の新しいインスタンスを作成し、コントロール コレクションに追加します。

  • SelectedIndexChanged イベントのイベント ハンドラーを追加します。

  • フォントの一覧が FontListBox 作成します。

  • 選択したフォントのサンプルを表示するラベルを提供します。

オーナー描画リスト ボックスを作成するには

  1. プロジェクトに、OwnerDrawnListBox カスタム コントロール クラスを追加します。

                                ' Base custom control for DrawFontList
                                Class OwnerDrawnListBox
        Inherits Control
        PrivateConst SCROLL_WIDTH AsInteger = 20
        Private itemH AsInteger = -1
        Private selIndex AsInteger = -1
    
        Private offScreenBitmap As Bitmap
        Private vs As VScrollBar
        Private itemsAList As ArrayList
    
    
        PublicSubNew()
            Me.vs = New VScrollBar
            Me.vs.Parent = MeMe.vs.Visible = FalseMe.vs.SmallChange = 1
            AddHandlerMe.vs.ValueChanged, AddressOfMe.ScrollValueChanged
    
            Me.itemsAList = New ArrayList
        EndSubPublicReadOnlyProperty Items() As ArrayList
            GetReturnMe.itemsAList
            EndGetEndPropertyProtectedReadOnlyProperty OffScreen() As Bitmap
            GetReturnMe.offScreenBitmap
            EndGetEndPropertyProtectedReadOnlyProperty VScrollBar() As VScrollBar
            GetReturnMe.vs
            EndGetEndPropertyFriendEvent SelectedIndexChanged As EventHandler
    
    
        ProtectedOverridableSub OnSelectedIndexChanged(ByVal e As EventArgs)
            RaiseEvent SelectedIndexChanged(Me, e)
        EndSubProtectedOverridesSub OnMouseDown(ByVal e As MouseEventArgs)
            Me.SelectedIndex = Me.vs.Value + e.Y / Me.ItemHeight
    
            ' Invalidate the control so we can draw the item as selected.Me.Refresh()
        EndSub
        ' Get or set index of selected item.PublicProperty SelectedIndex() AsIntegerGetReturnMe.selIndex
            EndGetSet(ByVal Value AsInteger)
                Me.selIndex = Value
    
                RaiseEvent SelectedIndexChanged(Me, Nothing)
            EndSetEndPropertyProtectedSub ScrollValueChanged(ByVal o AsObject, ByVal e As EventArgs)
            Me.Refresh()
        EndSubProtectedOverridableProperty ItemHeight() AsIntegerGetReturnMe.itemH
            EndGetSet(ByVal Value AsInteger)
                Me.itemH = Value
            EndSetEndProperty
    
        ' If the requested index is before the first visible index then set the    ' first item to be the requested index. If it is after the last visible    ' index, then set the last visible index to be the requested index.PublicSub EnsureVisible(ByVal index AsInteger)
            If index < Me.vs.Value ThenMe.vs.Value = index
                Me.Refresh()
            ElseIf index >= Me.vs.Value + Me.DrawCount ThenMe.vs.Value = index - Me.DrawCount + 1
                Me.Refresh()
            EndIfEndSub
    
        ' Need to set focus to the control when it     ' is clicked so that keyboard events occur.ProtectedOverridesSub OnClick(ByVal e As EventArgs)
            Me.Focus()
            MyBase.OnClick(e)
        EndSub
        ' Selected item moves when you use the keyboard up/down keys.ProtectedOverridesSub OnKeyDown(ByVal e As KeyEventArgs)
            SelectCase e.KeyCode
                Case Keys.Down
                    IfMe.SelectedIndex < Me.vs.Maximum ThenMe.SelectedIndex = Me.SelectedIndex + 1
                        EnsureVisible(Me.SelectedIndex + 1)
                        Me.Refresh()
                    EndIfCase Keys.Up
                    IfMe.SelectedIndex > Me.vs.Minimum ThenMe.SelectedIndex = Me.SelectedIndex - 1
                        EnsureVisible(Me.SelectedIndex - 1)
                        Me.Refresh()
                    EndIfCase Keys.PageDown
                    Me.SelectedIndex = Math.Min(Me.vs.Maximum, Me.SelectedIndex + Me.DrawCount)
                    EnsureVisible(Me.SelectedIndex)
                    Me.Refresh()
                Case Keys.PageUp
                    Me.SelectedIndex = Math.Max(Me.vs.Minimum, Me.SelectedIndex - Me.DrawCount)
                    EnsureVisible(Me.SelectedIndex)
                    Me.Refresh()
                Case Keys.Home
                    Me.SelectedIndex = 0
                    EnsureVisible(Me.SelectedIndex)
                    Me.Refresh()
                Case Keys.EndMe.SelectedIndex = Me.itemsAList.Count - 1
                    EnsureVisible(Me.SelectedIndex)
                    Me.Refresh()
            EndSelectMyBase.OnKeyDown(e)
        EndSub
        ' Calculate how many items we can draw given the height of the control.ProtectedReadOnlyProperty DrawCount() AsIntegerGetIfMe.vs.Value + Me.vs.LargeChange > Me.vs.Maximum ThenReturnMe.vs.Maximum - Me.vs.Value + 1
                ElseReturnMe.vs.LargeChange
                EndIfEndGetEndPropertyProtectedOverridesSub OnResize(ByVal e As EventArgs)
            Dim viewableItemCount AsInteger = Me.ClientSize.Height / Me.ItemHeight
    
            Me.vs.Bounds = New Rectangle(Me.ClientSize.Width - SCROLL_WIDTH, 0, SCROLL_WIDTH, Me.ClientSize.Height)
    
    
            ' Determine if scrollbars are neededIfMe.itemsAList.Count > viewableItemCount ThenMe.vs.Visible = TrueMe.vs.LargeChange = viewableItemCount
                Me.offScreenBitmap = New Bitmap(Me.ClientSize.Width - SCROLL_WIDTH - 1, Me.ClientSize.Height - 2)
            ElseMe.vs.Visible = FalseMe.vs.LargeChange = Me.itemsAList.Count
                Me.offScreenBitmap = New Bitmap(Me.ClientSize.Width - 1, Me.ClientSize.Height - 2)
            EndIfMe.vs.Maximum = Me.itemsAList.Count - 1
        EndSubEndClass
    
                                // Base custom control for DrawFontList
                                class OwnerDrawnListBox : Control
    {
        constint SCROLL_WIDTH = 20;
        int itemHeight         = -1;
        int selectedIndex      = -1;
    
        Bitmap offScreen;
        VScrollBar vs;
        ArrayList items;
    
        public OwnerDrawnListBox()
        {
            this.vs = new VScrollBar();
            this.vs.Parent      = this;
            this.vs.Visible     = false;
            this.vs.SmallChange = 1;
            this.vs.ValueChanged += new EventHandler(this.ScrollValueChanged);
    
            this.items = new ArrayList();
        }
    
        public ArrayList Items
        {
            get
            {
                returnthis.items;
            }
        }
    
        protected Bitmap OffScreen
        {
            get
            {
                returnthis.offScreen;
            }
        }
    
        protected VScrollBar VScrollBar
        {
            get
            {
                returnthis.vs;
            }
        }
    
        publicevent EventHandler SelectedIndexChanged;
    
        // Raise the SelectedIndexChanged eventprotectedvirtualvoid OnSelectedIndexChanged(EventArgs e)
        {
            if(this.SelectedIndexChanged != null)
                this.SelectedIndexChanged(this, e);
        }
    
        protectedoverridevoid OnMouseDown(MouseEventArgs e)
        {
            this.SelectedIndex = this.vs.Value + (e.Y / this.ItemHeight);
    
            // Invalidate the control so we can draw the item as selected.this.Refresh();
        }
    
        // Get or set index of selected item.publicint SelectedIndex
        {
            get
            {
                returnthis.selectedIndex;
            }
    
            set
            {
                this.selectedIndex = value;
    
                if (this.SelectedIndexChanged != null)
                    this.SelectedIndexChanged(this, EventArgs.Empty);
    
            }
        }
    
        protectedvoid ScrollValueChanged(object o, EventArgs e)
        {
            this.Refresh();
        }
    
        protectedvirtualint ItemHeight
        {
            get
            {
                returnthis.itemHeight;
            }
    
            set
            {
                this.itemHeight = value;
            }
        }
    
        // If the requested index is before the first visible index then set the// first item to be the requested index. If it is after the last visible// index, then set the last visible index to be the requested index.publicvoid EnsureVisible(int index)
        {
            if(index < this.vs.Value)
            {
                this.vs.Value = index;
                this.Refresh();
            }
            elseif(index >= this.vs.Value + this.DrawCount)
            {
                this.vs.Value = index - this.DrawCount + 1;
                this.Refresh();
            }
        }
    
    
        // Need to set focus to the control when it// is clicked so that keyboard events occur.protectedoverridevoid OnClick(EventArgs e)
        {
            this.Focus();
            base.OnClick(e);
        }
    
        // Selected item moves when you use the keyboard up/down keys.protectedoverridevoid OnKeyDown(KeyEventArgs e)
        {
            switch(e.KeyCode)
            {
                case Keys.Down:
                    if(this.SelectedIndex < this.vs.Maximum)
                    {
                        EnsureVisible(++this.SelectedIndex);
                        this.Refresh();
                    }
                    break;
                case Keys.Up:
                    if(this.SelectedIndex > this.vs.Minimum)
                    {
                        EnsureVisible(--this.SelectedIndex);
                        this.Refresh();
                    }
                    break;
                case Keys.PageDown:
                    this.SelectedIndex = Math.Min(this.vs.Maximum, this.SelectedIndex + this.DrawCount);
                    EnsureVisible(this.SelectedIndex);
                    this.Refresh();
                    break;
                case Keys.PageUp:
                    this.SelectedIndex = Math.Max(this.vs.Minimum, this.SelectedIndex - this.DrawCount);
                    EnsureVisible(this.SelectedIndex);
                    this.Refresh();
                    break;
                case Keys.Home:
                    this.SelectedIndex = 0;
                    EnsureVisible(this.SelectedIndex);
                    this.Refresh();
                    break;
                case Keys.End:
                    this.SelectedIndex = this.items.Count - 1;
                    EnsureVisible(this.SelectedIndex);
                    this.Refresh();
                    break;
            }
    
            base.OnKeyDown(e);
        }
    
        // Calculate how many items we can draw given the height of the control.protectedint DrawCount
        {
            get
            {
                if(this.vs.Value + this.vs.LargeChange > this.vs.Maximum)
                    returnthis.vs.Maximum - this.vs.Value + 1;
                elsereturnthis.vs.LargeChange;
            }
        }
    
        protectedoverridevoid OnResize(EventArgs e)
        {
            int viewableItemCount = this.ClientSize.Height / this.ItemHeight;
    
            this.vs.Bounds = new Rectangle(this.ClientSize.Width - SCROLL_WIDTH,
                0,
                SCROLL_WIDTH,
                this.ClientSize.Height);
    
    
            // Determine if scrollbars are neededif(this.items.Count > viewableItemCount)
            {
                this.vs.Visible = true;
                this.vs.LargeChange = viewableItemCount;
                this.offScreen = new Bitmap(this.ClientSize.Width - SCROLL_WIDTH - 1, this.ClientSize.Height - 2);
            }
            else
            {
                this.vs.Visible = false;
                this.vs.LargeChange = this.items.Count;
                this.offScreen = new Bitmap(this.ClientSize.Width - 1, this.ClientSize.Height - 2);
            }
    
            this.vs.Maximum = this.items.Count - 1;
        }
    }
    
  2. プロジェクトに、FontListBox クラス (これは OwnerDrawnListBox の実装) を追加します。

                                ' Derive an implementation of the
                                ' OwnerDrawnListBox class
                                Class FontListBox
        Inherits OwnerDrawnListBox
        PrivateConst FONT_SIZE AsInteger = 10
        PrivateConst DRAW_OFFSET AsInteger = 5
    
    
        PublicSubNew()
    
            ' Determine what the item height should be        ' by adding 30% padding after measuring        ' the letter A with the selected font.Dim g As Graphics = Me.CreateGraphics()
            Me.ItemHeight = Fix(g.MeasureString("A", Me.Font).Height * 1.3)
            g.Dispose()
        EndSub
        ' Return the name of the selected font.PublicReadOnlyProperty SelectedFaceName() AsStringGetReturnCStr(Me.Items(Me.SelectedIndex))
            EndGetEndProperty
    
        ' Determine what the text color should be    ' for the selected item drawn as highlightedFunction CalcTextColor(ByVal backgroundColor As Color) As Color
            If backgroundColor.Equals(Color.Empty) ThenReturn Color.Black
            EndIfDim sum AsInteger = backgroundColor.R + backgroundColor.G + backgroundColor.B
    
            If sum > 256 ThenReturn Color.Black
            ElseReturn Color.White
            EndIfEndFunctionProtectedOverridesSub OnPaint(ByVal e As PaintEventArgs)
            Dim font As Font
            Dim fontColor As Color
    
            ' The base class contains a bitmap, offScreen, for constructing        ' the control and is rendered when all items are populated.        ' This technique prevents flicker.Dim gOffScreen As Graphics = Graphics.FromImage(Me.OffScreen)
            gOffScreen.FillRectangle(New SolidBrush(Me.BackColor), Me.ClientRectangle)
    
            Dim itemTop AsInteger = 0
    
            ' Draw the fonts in the list.Dim n AsIntegerFor n = Me.VScrollBar.Value To (Me.VScrollBar.Value + DrawCount) - 1
                ' If the font name contains "dings" it needs to be displayed            ' in the list box with a readable font with the default font.IfCStr(Me.Items(n)).ToLower().IndexOf("dings") <> -1 Then
                    font = New Font(Me.Font.Name, FONT_SIZE, FontStyle.Regular)
                Else
                    font = New Font(CStr(Me.Items(n)), FONT_SIZE, FontStyle.Regular)
                EndIf            ' Draw the selected item to appear highlightedIf n = Me.SelectedIndex Then
                    gOffScreen.FillRectangle(New SolidBrush(SystemColors.Highlight), 1, itemTop + 1, Me.ClientSize.Width - IIf(Me.VScrollBar.Visible, Me.VScrollBar.Width, 2), Me.ItemHeight)
                    ' If the scroll bar is visible, subtract the scrollbar width                ' otherwise subtract 2 for the width of the rectangle
                    fontColor = CalcTextColor(SystemColors.Highlight)
                Else
                    fontColor = Me.ForeColor
                EndIf            ' Draw the item
                gOffScreen.DrawString(CStr(Me.Items(n)), font, New SolidBrush(fontColor), DRAW_OFFSET, itemTop)
                itemTop += Me.ItemHeight
            Next n
    
            ' Draw the list box
            e.Graphics.DrawImage(Me.OffScreen, 1, 1)
    
            gOffScreen.Dispose()
        EndSub
    
        ' Draws the external border around the control.ProtectedOverridesSub OnPaintBackground(ByVal e As PaintEventArgs)
            e.Graphics.DrawRectangle(New Pen(Color.Black), 0, 0, Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)
        EndSubEndClass
    
                                // Derive an implementation of the
                                // OwnerDrawnListBox class
                                class FontListBox : OwnerDrawnListBox
    {
        constint FONT_SIZE    = 10;
        constint DRAW_OFFSET  = 5;
    
        public FontListBox()
        {
    
            // Determine what the item height should be// by adding 30% padding after measuring// the letter A with the selected font.
            Graphics g = this.CreateGraphics();
            this.ItemHeight = (int)(g.MeasureString("A", this.Font).Height * 1.3);
            g.Dispose();
        }
    
        // Return the name of the selected font.publicstring SelectedFaceName
        {
            get
            {
                return (string)this.Items[this.SelectedIndex];
            }
        }
    
        // Determine what the text color should be// for the selected item drawn as highlighted
        Color CalcTextColor(Color backgroundColor)
        {
            if(backgroundColor.Equals(Color.Empty))
                return Color.Black;
    
            int sum = backgroundColor.R + backgroundColor.G + backgroundColor.B;
    
            if(sum > 256)
                return Color.Black;
            elsereturn Color.White;
        }
    
        protectedoverridevoid OnPaint(PaintEventArgs e)
        {
            Font font;
            Color fontColor;
    
            // The base class contains a bitmap, offScreen, for constructing// the control and is rendered when all items are populated.// This technique prevents flicker.
            Graphics gOffScreen = Graphics.FromImage(this.OffScreen);
            gOffScreen.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
    
            int itemTop = 0;
    
            // Draw the fonts in the list.for(int n = this.VScrollBar.Value; n < this.VScrollBar.Value + DrawCount; n++)
            {
                // If the font name contains "dings" it needs to be displayed
                // in the list box with a readable font with the default font.if(((string)this.Items[n]).ToLower().IndexOf("dings") != -1)
                    font = new Font(this.Font.Name, FONT_SIZE, FontStyle.Regular);
                else
                    font = new Font((string)this.Items[n], FONT_SIZE, FontStyle.Regular);
    
                // Draw the selected item to appear highlightedif(n == this.SelectedIndex)
                {
                    gOffScreen.FillRectangle(new SolidBrush(SystemColors.Highlight),
                        1,
                        itemTop + 1,
                        // If the scroll bar is visible, subtract the scrollbar width// otherwise subtract 2 for the width of the rectanglethis.ClientSize.Width - (this.VScrollBar.Visible ? this.VScrollBar.Width : 2),
                        this.ItemHeight);
                    fontColor = CalcTextColor(SystemColors.Highlight);
                }
                else
                    fontColor = this.ForeColor;
    
                // Draw the item
                gOffScreen.DrawString((string)this.Items[n], font, new SolidBrush(fontColor), DRAW_OFFSET, itemTop);
                itemTop += this.ItemHeight;
            }
    
            // Draw the list box
            e.Graphics.DrawImage(this.OffScreen, 1, 1);
    
            gOffScreen.Dispose();
        }
    
        // Draws the external border around the control.protectedoverridevoid OnPaintBackground(PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(new Pen(Color.Black), 0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1);
        }
    }
    
  3. フォームで、2 つの Label コントロール追加し、 descLabel および sampleLabel; 名前を付けます後者の場合が表示、フォントの使用例 FontListBox から選択されます。

  4. FontListBox フォームのインスタンスを作成します。

  5. フォームに対する Load イベントのコンストラクターに次のコードを追加します。

                                ' Create a new instance of FontListBox.
    myListBox.Parent = Me
    ' Configure the event handler for the SelectedIndexChanged event. AddHandler myListBox.SelectedIndexChanged, AddressOfMe.SelectedIndexChanged
    
    ' Draw the bounds of the FontListBox.
    myListBox.Bounds = New Rectangle(5, 5, 150, 100)
    
    ' Add fonts to list, repeat the list 4 times' so that the scroll bar can be demonstrated.Dim n AsIntegerFor n = 0 To 3
        myListBox.Items.Add("Bookdings")
        myListBox.Items.Add("Courier New")
        myListBox.Items.Add("Frutiger Linotype")
        myListBox.Items.Add("Tahoma")
    Next n
    
    
    ' Labels to show the selected font from the list box. Assumes' instances of these labels have been declared for the form.
    descLabel.Parent = Me
    descLabel.Text = "Font Sample:"
    descLabel.Bounds = New Rectangle(10, myListBox.Bottom + 20, Me.ClientSize.Width - 10, 30)
    
    ' Assumes an instance sampleLabel is declared for the form.
    sampleLabel.Parent = Me
    sampleLabel.Bounds = New Rectangle(10, descLabel.Bottom, Me.ClientSize.Width - 10, 30)
    sampleLabel.Text = "AaBbCc 123"
    
                                // Create a new instance of FontListBox.
    box = new FontListBox();
    box.Parent = this;
    
    // Configure the event handler for the SelectedIndexChanged event.
    box.SelectedIndexChanged += new EventHandler(this.SelectedIndexChanged);
    
    // Draw the bounds of the FontListBox.
    box.Bounds = new Rectangle(5, 5, 150, 100);
    
    // Add fonts to list, repeat the list 4 times// so that the scroll bar can be demonstrated.for(int n = 0; n < 4; n++)
    {
        box.Items.Add("Bookdings");
        box.Items.Add("Courier New");
        box.Items.Add("Frutiger Linotype");
        box.Items.Add("Tahoma");
    }
    
    
    // Labels to show the selected font and a sample.
    Label desc = new Label();
    desc.Parent = this;
    desc.Text = "Font Sample:";
    desc.Bounds = new Rectangle(10, box.Bottom + 20, this.ClientSize.Width - 10, 30);
    
    sample = new Label();
    sample.Parent = this;
    sample.Bounds = new Rectangle(10, desc.Bottom, this.ClientSize.Width - 10, 30);
    sample.Text = "AaBbCc 123";
    
  6. コード SelectedChangedEventFontListBox コントロールで選択されているフォントを表示する、 sampleLabel コントロールのイベントを追加します。

                                ' Event handler for SelectedIndexChanged to
                                ' display a sample of the selected font.
    
    ' Assumes that an instace of myListBox has been declared for the form.
                                Friend
                                Sub SelectedIndexChanged(ByVal o AsObject, ByVal e As EventArgs)
        sampleLabel.Font = New Font(myListBox.SelectedFaceName, 12, FontStyle.Regular)
    EndSub
    
                                // Event handler for SelectedIndexChanged to
                                // display a sample of the selected font.
                                private
                                void SelectedIndexChanged(object o, EventArgs e)
    {
        sample.Font = new Font(box.SelectedFaceName, 12, FontStyle.Regular);
    }
    

コードのコンパイル方法

この例では、次の名前空間への参照が必要です。

参照

概念

カスタム コントロールの開発

.NET コンパクトなフレームワーク方法を説明したトピックの検索