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:OUGEQ%(E-Mail Removed)...
> [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.
>
|