Skip to content

Instantly share code, notes, and snippets.

@jpoehls
Created April 18, 2010 01:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpoehls/369936 to your computer and use it in GitHub Desktop.
Save jpoehls/369936 to your computer and use it in GitHub Desktop.
CascadingListDecorator for WinForms
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Samples
{
public class CascadingListDecorator<TChildValue, TParentValue> where TParentValue : class
{
private ListControl _childList;
private Func<TParentValue, IList<TChildValue>> _DynamicDataSource;
private ListControl _parentList;
public CascadingListDecorator(ListControl child)
{
_childList = child;
_childList.Enabled = false;
AutoSelectSoloItem = false;
}
public Func<TParentValue, IList<TChildValue>> DynamicDataSource
{
get { return _DynamicDataSource; }
set
{
_DynamicDataSource = value;
RefreshData();
}
}
public ListControl ParentList
{
get { return _parentList; }
set
{
if (_parentList != null)
{
_parentList.SelectedValueChanged -= ParentListItemsChanged;
_parentList.DataSourceChanged -= ParentListItemsChanged;
}
_parentList = value;
_parentList.SelectedValueChanged += ParentListItemsChanged;
_parentList.DataSourceChanged += ParentListItemsChanged;
RefreshData();
}
}
public bool AutoSelectSoloItem { get; set; }
protected void ParentListItemsChanged(object sender, EventArgs e)
{
RefreshData();
}
protected object lastParentSelectedValue;
public void RefreshData()
{
object parentSelectedValue = null;
// .SelectedValue property throws an exception
// if the underlying data source has changed
// and the SelectedIndex is invalid.
try
{
parentSelectedValue = _parentList.SelectedValue;
}
// ReSharper disable EmptyGeneralCatchClause
catch
// ReSharper restore EmptyGeneralCatchClause
{ }
int childSelectedIndex = -1;
if (lastParentSelectedValue == parentSelectedValue)
{
childSelectedIndex = _childList.SelectedIndex;
}
lastParentSelectedValue = parentSelectedValue;
if (parentSelectedValue != null && DynamicDataSource != null)
{
_childList.Enabled = true;
var items = DynamicDataSource(_parentList.SelectedValue as TParentValue);
_childList.DataSource = items;
if (AutoSelectSoloItem && childSelectedIndex == -1 && items.Count == 1)
{
_childList.SelectedIndex = 0;
}
else
{
_childList.SelectedIndex = childSelectedIndex;
}
}
else
{
_childList.DataSource = null;
_childList.SelectedIndex = -1;
_childList.Enabled = false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment