?? datalistview.cs
字號(hào):
if (hasBooleanColumns)
this.SetupSubItemCheckBoxes();
}
/// <summary>
/// Generate aspect getters and putters for any columns that are missing them (and for which we have
/// enough information to actually generate a getter)
/// </summary>
protected virtual void CreateMissingAspectGettersAndPutters()
{
for (int i = 0; i < this.Columns.Count; i++) {
OLVColumn column = this.GetColumn(i);
if (column.AspectGetter == null && !String.IsNullOrEmpty(column.AspectName)) {
column.AspectGetter = delegate(object row) {
// In most cases, rows will be DataRowView objects
DataRowView drv = row as DataRowView;
if (drv != null)
return drv[column.AspectName];
else
return column.GetAspectByName(row);
};
}
if (column.IsEditable && column.AspectPutter == null && !String.IsNullOrEmpty(column.AspectName)) {
column.AspectPutter = delegate(object row, object newValue) {
// In most cases, rows will be DataRowView objects
DataRowView drv = row as DataRowView;
if (drv != null)
drv[column.AspectName] = newValue;
else
column.PutAspectByName(row, newValue);
};
}
}
}
#endregion
#region Object manipulations
/// <summary>
/// Add the given collection of model objects to this control.
/// </summary>
/// <param name="modelObjects">A collection of model objects</param>
/// <remarks>This is a no-op for data lists, since the data
/// is controlled by the DataSource. Manipulate the data source
/// rather than this view of the data source.</remarks>
public override void AddObjects(ICollection modelObjects)
{
}
/// <summary>
/// Remove the given collection of model objects from this control.
/// </summary>
/// <remarks>This is a no-op for data lists, since the data
/// is controlled by the DataSource. Manipulate the data source
/// rather than this view of the data source.</remarks>
public override void RemoveObjects(ICollection modelObjects)
{
}
#endregion
#region Event Handlers
/// <summary>
/// What should we do when the list is unfrozen
/// </summary>
protected override void DoUnfreeze()
{
this.RebindDataSource(true);
}
/// <summary>
/// Handles binding context changes
/// </summary>
/// <param name="e">The EventArgs that will be passed to any handlers
/// of the BindingContextChanged event.</param>
protected override void OnBindingContextChanged(EventArgs e)
{
base.OnBindingContextChanged(e);
// If our binding context changes, we must rebind, since we will
// have a new currency managers, even if we are still bound to the
// same data source.
this.RebindDataSource(false);
}
/// <summary>
/// Handles parent binding context changes
/// </summary>
/// <param name="e">Unused EventArgs.</param>
protected override void OnParentBindingContextChanged(EventArgs e)
{
base.OnParentBindingContextChanged(e);
// BindingContext is an ambient property - by default it simply picks
// up the parent control's context (unless something has explicitly
// given us our own). So we must respond to changes in our parent's
// binding context in the same way we would changes to our own
// binding context.
this.RebindDataSource(false);
}
// CurrencyManager ListChanged event handler.
// Deals with fine-grained changes to list items.
// It's actually difficult to deal with these changes in a fine-grained manner.
// If our listview is grouped, then any change may make a new group appear or
// an old group disappear. It is rarely enough to simply update the affected row.
protected virtual void currencyManager_ListChanged(object sender, ListChangedEventArgs e)
{
switch (e.ListChangedType) {
// Well, usually fine-grained... The whole list has changed utterly, so reload it.
case ListChangedType.Reset:
this.InitializeDataSource();
break;
// A single item has changed, so just refresh that.
// TODO: Even in this simple case, we should probably rebuild the list.
case ListChangedType.ItemChanged:
Object changedRow = this.currencyManager.List[e.NewIndex];
this.RefreshObject(changedRow);
break;
// A new item has appeared, so add that.
// We get this event twice if certain grid controls are used to add a new row to a
// datatable: once when the editing of a new row begins, and once again when that
// editing commits. (If the user cancels the creation of the new row, we never see
// the second creation.) We detect this by seeing if this is a view on a row in a
// DataTable, and if it is, testing to see if it's a new row under creation.
case ListChangedType.ItemAdded:
Object newRow = this.currencyManager.List[e.NewIndex];
DataRowView drv = newRow as DataRowView;
if (drv == null || !drv.IsNew) {
// Either we're not dealing with a view on a data table, or this is the commit
// notification. Either way, this is the final notification, so we want to
// handle the new row now!
this.InitializeDataSource();
}
break;
// An item has gone away.
case ListChangedType.ItemDeleted:
this.InitializeDataSource();
break;
// An item has changed its index.
case ListChangedType.ItemMoved:
this.InitializeDataSource();
break;
// Something has changed in the metadata.
// CHECK: When are these events actually fired?
case ListChangedType.PropertyDescriptorAdded:
case ListChangedType.PropertyDescriptorChanged:
case ListChangedType.PropertyDescriptorDeleted:
this.InitializeDataSource();
break;
}
}
// The CurrencyManager calls this if the data source looks
// different. We just reload everything.
// CHECK: Do we need this if we are handle ListChanged metadata events?
protected virtual void currencyManager_MetaDataChanged(object sender, EventArgs e)
{
this.InitializeDataSource();
}
// Called by the CurrencyManager when the currently selected item
// changes. We update the ListView selection so that we stay in sync
// with any other controls bound to the same source.
protected virtual void currencyManager_PositionChanged(object sender, EventArgs e)
{
int index = this.currencyManager.Position;
// Make sure the index is sane (-1 pops up from time to time)
if (index < 0 || index >= this.Items.Count)
return;
// Avoid recursion. If we are currently changing the index, don't
// start the process again.
if (this.isChangingIndex)
return;
try {
this.isChangingIndex = true;
// We can't use the index directly, since our listview may be sorted
this.SelectedObject = this.currencyManager.List[index];
// THINK: Do we always want to bring it into view?
if (this.SelectedItems.Count > 0)
this.SelectedItems[0].EnsureVisible();
}
finally {
this.isChangingIndex = false;
}
}
private bool isChangingIndex = false;
/// <summary>
/// Handle a SelectedIndexChanged event
/// </summary>
/// <param name="e">The event</param>
/// <remarks>
/// Called by Windows Forms when the currently selected index of the
/// control changes. This usually happens because the user clicked on
/// the control. In this case we want to notify the CurrencyManager so
/// that any other bound controls will remain in sync. This method will
/// also be called when we changed our index as a result of a
/// notification that originated from the CurrencyManager, and in that
/// case we avoid notifying the CurrencyManager back!
/// </remarks>
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
// Prevent recursion
if (this.isChangingIndex)
return;
// If we are bound to a datasource, and only one item is selected,
// tell the currency manager which item is selected.
if (this.SelectedIndices.Count == 1 && this.currencyManager != null) {
try {
this.isChangingIndex = true;
// We can't use the selectedIndex directly, since our listview may be sorted.
// So we have to find the index of the selected object within the original list.
this.currencyManager.Position = this.currencyManager.List.IndexOf(this.SelectedObject);
}
finally {
this.isChangingIndex = false;
}
}
}
#endregion
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -