Created
April 18, 2010 01:05
-
-
Save jpoehls/369936 to your computer and use it in GitHub Desktop.
CascadingListDecorator for WinForms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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