467,880 Members | 1,255 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,880 developers. It's quick & easy.

copying the listbox behaviour in "Add/Remove Programs"

[Problem]
I'm looking to develop a listbox with in-place editing where as each item is
selected, it grows to fit in all the text boxes. When the item is
deselected, it shrinks back to its original size. The editing bit is not a
problem, but I can't get the selected item to resize, as the listbox does
for the "Add/Remove programs".

[Approach]
The initial thought I had was to have a handler for the MeasureItem event,
then have the condition of whether the current index was selected or not,
basing the height on this.
The SelectionChange event would then call a refresh on the list box, which
in turn would cause the MeasureItem event to fire, finally leaving the
DrawItem event handler to draw the items as required.
Is this thinking logical and workable?

[code]
protected void _listBox_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index < 0 )
{
selectionPanel.Hide();
return;
}

if ( (e.State & DrawItemState.Selected) ==
DrawItemState.Selected )
{
// The e.Bounds rect appears to remain unchange from the
initial
// MeasureItem event handler settings, and any changes made
// after this seems to be ignored when getting to this
method.

// put the editing panel in the selection spot
selectionPanel.Size = new Size ( e.Bounds.Width,
e.Bounds.Height );
selectionPanel.Location = new Point ( e.Bounds.Location.X+1,
e.Bounds.Location.Y+1 );
selectionPanel.BackColor = SelectedBackgroundColor;
selectionPanel.Show();

}
else
{
// draw unselected items
DrawInterfaceItem(
((InboundInterface)(_itemArray[e.Index])).name,
((InboundInterface)(_itemArray[e.Index])).type,
((InboundInterface)(_itemArray[e.Index])).messageType,
e );
}
}

private void _listBox_MeasureItem(object sender,
System.Windows.Forms.MeasureItemEventArgs e)
{
// this does indeed fire on each selection change and
// can trace the e.ItemHeight being set for selected
// items as expected.
if ( _listBox.SelectedIndex == e.Index )
{
// set the item height to that of the selection panel
e.ItemHeight = selectionPanel.Height;
}
else
{
// items not selected use a default item height
e.ItemHeight = _defaultItemHeight;
}
}

private void _listBox_SelectedIndexChanged(object sender,
System.EventArgs e)
{
// cause a redraw, and MeasureItem to fire
_listBox.Refresh();
}

Thanks for your time.
Dan.
Nov 16 '05 #1
  • viewed: 2354
Share:
1 Reply
I managed to get this to work! Think I feel a article coming on...

It's done in short, on the following principle:
- When you reinsert an item, it fires the MeasureItem event for that item.
- You need to reinsert the newly selected index, as well as the last
selectedIndex...

Hope this helps someone else.

[code]

bool _updatingSelectedIndex = false;
bool _processingSelectionChange = false;
int _lastSelectedIndex = -1;

private void _listBox_MeasureItem(object sender,
System.Windows.Forms.MeasureItemEventArgs e)
{
if ( _updatingSelectedIndex )
{
e.ItemHeight = selectionPanel.Height;
}
else
{
e.ItemHeight = _defaultItemHeight;
}
}

private void _listBox_SelectedIndexChanged(object sender,
System.EventArgs e)
{
if ( _listBox.Items.Count <= 0 )
{
return;
}

if ( !_processingSelectionChange )
{
_processingSelectionChange = true;

// re-evaulate the last selected item height
if ( _lastSelectedIndex >= 0 )
{
int position = _lastSelectedIndex;
Object item = _listBox.Items[position];
_listBox.Items.RemoveAt(position);
_listBox.Items.Insert(position, item);
}

_lastSelectedIndex = _listBox.SelectedIndex;

if ( !_updatingSelectedIndex && _listBox.SelectedIndex >=
)
{
_updatingSelectedIndex = true;

// re-evaulate the selected item height
int position = _listBox.SelectedIndex;
Object item = _listBox.Items[position];
_listBox.Items.RemoveAt(position);
_listBox.Items.Insert(position, item);
_listBox.SelectedIndex = position;

_updatingSelectedIndex = false;

}

_processingSelectionChange = false;

}

}

"Dan Bass" <Not Listed> wrote in message
news:OU****************@TK2MSFTNGP09.phx.gbl...
[Problem]
I'm looking to develop a listbox with in-place editing where as each item
is selected, it grows to fit in all the text boxes. When the item is
deselected, it shrinks back to its original size. The editing bit is not a
problem, but I can't get the selected item to resize, as the listbox does
for the "Add/Remove programs".

[Approach]
The initial thought I had was to have a handler for the MeasureItem event,
then have the condition of whether the current index was selected or not,
basing the height on this.
The SelectionChange event would then call a refresh on the list box, which
in turn would cause the MeasureItem event to fire, finally leaving the
DrawItem event handler to draw the items as required.
Is this thinking logical and workable?

[code]
protected void _listBox_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
if ( e.Index < 0 )
{
selectionPanel.Hide();
return;
}

if ( (e.State & DrawItemState.Selected) ==
DrawItemState.Selected )
{
// The e.Bounds rect appears to remain unchange from the
initial
// MeasureItem event handler settings, and any changes made
// after this seems to be ignored when getting to this
method.

// put the editing panel in the selection spot
selectionPanel.Size = new Size ( e.Bounds.Width,
e.Bounds.Height );
selectionPanel.Location = new Point (
e.Bounds.Location.X+1, e.Bounds.Location.Y+1 );
selectionPanel.BackColor = SelectedBackgroundColor;
selectionPanel.Show();

}
else
{
// draw unselected items
DrawInterfaceItem(
((InboundInterface)(_itemArray[e.Index])).name,
((InboundInterface)(_itemArray[e.Index])).type,
((InboundInterface)(_itemArray[e.Index])).messageType,
e );
}
}

private void _listBox_MeasureItem(object sender,
System.Windows.Forms.MeasureItemEventArgs e)
{
// this does indeed fire on each selection change and
// can trace the e.ItemHeight being set for selected
// items as expected.
if ( _listBox.SelectedIndex == e.Index )
{
// set the item height to that of the selection panel
e.ItemHeight = selectionPanel.Height;
}
else
{
// items not selected use a default item height
e.ItemHeight = _defaultItemHeight;
}
}

private void _listBox_SelectedIndexChanged(object sender,
System.EventArgs e)
{
// cause a redraw, and MeasureItem to fire
_listBox.Refresh();
}

Thanks for your time.
Dan.

Nov 16 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by eksamor | last post: by
1 post views Thread by =?Utf-8?B?U3B1dG5pY2s=?= | last post: by
4 posts views Thread by Sean DiZazzo | last post: by
reply views Thread by MrMoon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.