-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add combo box and list box for dynamic collections
- Loading branch information
Showing
6 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.ComponentModel; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Represents an operator that interfaces with a combo box control bound to each data | ||
/// source in the sequence and generates notifications whenever the selection changes. | ||
/// </summary> | ||
[TypeVisualizer(typeof(ComboBoxDataSourceVisualizer))] | ||
[Description("Interfaces with a combo box control bound to each data source in the sequence and generates notifications whenever the selection changes.")] | ||
public class ComboBoxDataSourceBuilder : ListControlDataSourceBuilderBase | ||
{ | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
using System.Drawing; | ||
using System.Windows.Forms; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Provides a type visualizer representing a combo box control bound | ||
/// to an arbitrary data source. | ||
/// </summary> | ||
public class ComboBoxDataSourceVisualizer : ControlVisualizerBase<ComboBox, ComboBoxDataSourceBuilder> | ||
{ | ||
/// <inheritdoc/> | ||
protected override ComboBox CreateControl(IServiceProvider provider, ComboBoxDataSourceBuilder builder) | ||
{ | ||
var comboBox = new ComboBox(); | ||
comboBox.Dock = DockStyle.Fill; | ||
comboBox.Size = new Size(300, 150); | ||
comboBox.SubscribeTo(builder._DisplayMember, value => comboBox.DisplayMember = value); | ||
comboBox.SubscribeTo(builder._DataSource, value => comboBox.DataSource = value); | ||
comboBox.SelectedIndexChanged += (sender, e) => | ||
{ | ||
var index = comboBox.SelectedIndex; | ||
var selectedValue = index < 0 ? null : comboBox.Items[index]; | ||
builder._SelectedItem.OnNext(selectedValue); | ||
}; | ||
return comboBox; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Provides an abstract base class for UI controls which can be bound to each | ||
/// data source from an observable sequence. | ||
/// </summary> | ||
public abstract class DataSourceControlBuilderBase : ControlBuilderBase | ||
{ | ||
static readonly Range<int> argumentRange = Range.Create(lowerBound: 1, upperBound: 1); | ||
|
||
/// <summary> | ||
/// Gets the range of input arguments that this expression builder accepts. | ||
/// </summary> | ||
public override Range<int> ArgumentRange => argumentRange; | ||
|
||
/// <summary> | ||
/// Builds the expression tree for configuring and calling the UI control. | ||
/// </summary> | ||
/// <inheritdoc/> | ||
public override Expression Build(IEnumerable<Expression> arguments) | ||
{ | ||
var source = arguments.First(); | ||
var sourceType = source.Type.GetGenericArguments()[0]; | ||
var valueType = ExpressionHelper.GetGenericTypeBindings(typeof(IList<>), sourceType); | ||
return Expression.Call(Expression.Constant(this), nameof(Generate), valueType, source); | ||
} | ||
|
||
/// <summary> | ||
/// Generates an observable sequence of values containing the currently | ||
/// selected item from the data source whenever the selection changes. | ||
/// </summary> | ||
/// <typeparam name="TValue"> | ||
/// The type of the values in the data source. | ||
/// </typeparam> | ||
/// <param name="source"> | ||
/// A sequence of collections representing the data sources to bind to | ||
/// the UI control. Only one collection is bound at any one time. | ||
/// </param> | ||
/// <returns> | ||
/// A sequence of values representing the currently selected item in | ||
/// the UI control. | ||
/// </returns> | ||
protected abstract IObservable<TValue> Generate<TValue>(IObservable<IList<TValue>> source); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.ComponentModel; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Represents an operator that interfaces with a list box control bound to each data | ||
/// source in the sequence and generates notifications whenever the selection changes. | ||
/// </summary> | ||
[TypeVisualizer(typeof(ListBoxDataSourceVisualizer))] | ||
[Description("Interfaces with a list box control bound to each data source in the sequence and generates notifications whenever the selection changes.")] | ||
public class ListBoxDataSourceBuilder : ListControlDataSourceBuilderBase | ||
{ | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
using System.Drawing; | ||
using System.Windows.Forms; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Provides a type visualizer representing a list box control bound | ||
/// to an arbitrary data source. | ||
/// </summary> | ||
public class ListBoxDataSourceVisualizer : ControlVisualizerBase<ListBox, ListBoxDataSourceBuilder> | ||
{ | ||
/// <inheritdoc/> | ||
protected override ListBox CreateControl(IServiceProvider provider, ListBoxDataSourceBuilder builder) | ||
{ | ||
var listBox = new ListBox(); | ||
listBox.Dock = DockStyle.Fill; | ||
listBox.Size = new Size(300, 150); | ||
listBox.SubscribeTo(builder._DisplayMember, value => listBox.DisplayMember = value); | ||
listBox.SubscribeTo(builder._DataSource, value => listBox.DataSource = value); | ||
listBox.SelectedIndexChanged += (sender, e) => | ||
{ | ||
var index = listBox.SelectedIndex; | ||
var selectedValue = index < 0 ? null : listBox.Items[index]; | ||
builder._SelectedItem.OnNext(selectedValue); | ||
}; | ||
return listBox; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
using System.Drawing.Design; | ||
using System.Linq; | ||
using System.Reactive; | ||
using System.Reactive.Disposables; | ||
using System.Reactive.Linq; | ||
using System.Reactive.Subjects; | ||
|
||
namespace Bonsai.Gui | ||
{ | ||
/// <summary> | ||
/// Provides an abstract base class for interfacing with combo box and list box controls | ||
/// bound to each data source in an observable sequence. | ||
/// </summary> | ||
public class ListControlDataSourceBuilderBase : DataSourceControlBuilderBase | ||
{ | ||
internal readonly BehaviorSubject<string> _DisplayMember = new(string.Empty); | ||
internal readonly BehaviorSubject<object> _DataSource = new(null); | ||
internal readonly BehaviorSubject<object> _SelectedItem = new(null); | ||
|
||
/// <summary> | ||
/// Gets or sets the property to display for this list control. | ||
/// </summary> | ||
[Editor(typeof(DataMemberSelectorEditor), typeof(UITypeEditor))] | ||
[Description("The property to display for this list control.")] | ||
public string DisplayMember | ||
{ | ||
get => _DisplayMember.Value; | ||
set => _DisplayMember.OnNext(value); | ||
} | ||
|
||
/// <summary> | ||
/// Generates an observable sequence of values containing the currently | ||
/// selected item in the list control whenever the selection changes. | ||
/// </summary> | ||
/// <typeparam name="TValue"> | ||
/// The type of the values in the data source. | ||
/// </typeparam> | ||
/// <param name="source"> | ||
/// A sequence of collections representing the data sources to bind to | ||
/// the list control. Only one collection is bound at any one time. | ||
/// </param> | ||
/// <returns> | ||
/// A sequence of values representing the currently selected item in | ||
/// the list control. | ||
/// </returns> | ||
protected override IObservable<TValue> Generate<TValue>(IObservable<IList<TValue>> source) | ||
{ | ||
return Observable.Create<TValue>(observer => | ||
{ | ||
var sourceObserver = Observer.Create<IList<TValue>>(collection => | ||
{ | ||
_SelectedItem.OnNext(null); | ||
_DataSource.OnNext(collection); | ||
}, observer.OnError); | ||
var selectedItem = _SelectedItem.Where(value => value is TValue).Cast<TValue>(); | ||
return new CompositeDisposable( | ||
selectedItem.SubscribeSafe(observer), | ||
source.SubscribeSafe(sourceObserver), | ||
Disposable.Create(() => | ||
{ | ||
_DataSource.OnNext(null); | ||
_SelectedItem.OnNext(null); | ||
})); | ||
}); | ||
} | ||
} | ||
} |