EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

如何:实现自定义WinForms列表编辑器

eXpressApp框架附带了一些在内置列表编辑器。但是,在某些情况下,您可能需要实现自定义列表编辑器,以特定方式显示对象集合。本主题演示如何实现使用.NET Framework库中的控件的自定义WinCustomListEditor列表编辑器。此列表编辑器旨在显示对象,将自定义IPictureItem接口实现为图像列表,每个对象一个。例如,它可用于显示DVD封面。

下图演示了在专辑列表视图中实现的列表编辑器:

WinThumbnailEditor

注意

您可以在XAF随附的FeatureCenter演示中看到此处实现的代码。默认情况下,此演示位于%PUBLIC%\ Documents \ DevExpress演示19.2 \ Components \ eXpressApp Framework \ FeatureCenter文件夹中。

提示

若要了解如何支持WinCustomListEditor的上下文菜单,请参阅“如何:支持自定义WinForms列表编辑器的上下文菜单”主题。

当实现用于特定数据的自定义列表编辑器时,可以为特定的类设计它。但是,在此示例中,将引入一个包含列表编辑器所需属性的接口。然后,将设计列表编辑器以显示实现该接口的对象。这种方法使您可以将同一列表编辑器同时用于不同的类。使用WinCustomListEditor显示的列表视图将具有两列:ImageText。特殊接口具有一个附加的ID属性,该属性表示唯一的对象标识符。

using System.Drawing;
//...
interface IPictureItem {
    Image Image { get; }
    string Text { get; }
    string ID { get; }
}

通过从ListEditor类继承其类来开始实现List Editor ,并通过覆盖以下成员来实现基本功能。请注意,您的编辑器应该是公开的。

  • CreateControlsCore方法,该方法实例化列表编辑器的控件。覆盖它以创建和配置控件。
  • AssignDataSourceToControl方法,用于将列表编辑器的数据源分配给其控件。当数据源实现IBindingList接口时,重写它以支持对象更改通知。
  • ListEditor.Refresh方法,用于刷新列表编辑器控件中的数据。重写它可以使控件从其数据源重新加载所有对象。
  • ListEditor.Dispose方法,该方法处理手动分配的controlDataSource属性。
  • 若要指定显示IPictureItem的列表视图,对象应使用WinCustomListEditor,并用ListEditorAttribute装饰列表编辑器类。

演示的列表编辑器可以显示实现IPictureItem接口的对象的集合。但是,它不支持项目选择,因为它无法识别当前选择了哪个项目。为了支持选择,必须修改以下成员:

  • CreateControlsCore方法中,订阅控件的SelectedIndexChangedItemSelectionChanged事件。在SelectedIndexChanged事件处理程序中,调用OnSelectionChanged方法。在ItemSelectionChanged事件处理程序中,调用OnSelectionChangedOnFocusedObjectChanged方法。
  • 重写ListEditor.SelectionType属性。由于ListView控件同时支持单个和多个选择,因此此属性必须返回SelectionType.Full
  • 重写ListEditor.GetSelectedObjects方法。此方法必须返回所选对象的列表。

除了选择之外,当最终用户按ENTER或双击对象时,列表编辑器还应该能够为焦点对象调用详细视图。为此,请修改以下成员:

  • CreateControlsCore方法中,订阅控件的MouseDoubleClickKeyDown事件。在事件处理程序中,调用OnProcessSelectedItem方法。
  • 重写ListEditor.FocusedObject属性,以获取并设置焦点对象。为此,我们实现了一个附加的FindByTag帮助器方法。
  • 修改ListEditor.Refresh方法,以使列表编辑器在刷新控件中的数据时保持焦点。

如果需要在应用程序模型中存储编辑器设置,请实现ListEditor.SaveModel方法。否则,将此方法留空

此代码段演示了上述步骤。

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Templates;
using DevExpress.ExpressApp.Utils;
using DevExpress.ExpressApp.Win.Controls;
using DevExpress.ExpressApp.Win.SystemModule;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars;
// ...
[ListEditor(typeof(IPictureItem))]
public class WinCustomListEditor : ListEditor {
    private System.Windows.Forms.ListView control;
    private System.Windows.Forms.ImageList images;
    private Object controlDataSource;
    private void dataSource_ListChanged(object sender, ListChangedEventArgs e) {
        Refresh();
    }
    private void control_MouseDoubleClick(object sender, MouseEventArgs e) {
        if(e.Button == MouseButtons.Left) {
            OnProcessSelectedItem();
        }
    }
    private void control_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
        if(e.KeyCode == Keys.Enter) {
            OnProcessSelectedItem();
        }
    }
    private void control_ItemSelectionChanged(object sender, System.Windows.Forms.ListViewItemSelectionChangedEventArgs e) {
        OnSelectionChanged();
    }
    private void control_SelectedIndexChanged(object sender, EventArgs e) {
        OnSelectionChanged();
        OnFocusedObjectChanged();
    }
    private System.Windows.Forms.ListViewItem FindByTag(object tag) {
        IPictureItem itemToSearch = (IPictureItem)tag;
        if(control != null && itemToSearch != null) {
            foreach(System.Windows.Forms.ListViewItem item in control.Items) {
                if(((IPictureItem)item.Tag).ID == itemToSearch.ID)
                    return item;
            }
        }
        return null;
    }
    protected override object CreateControlsCore() {
        control = new System.Windows.Forms.ListView();
        control.Sorting = SortOrder.Ascending;
        images = new System.Windows.Forms.ImageList();
        images.ImageSize = new System.Drawing.Size(104, 150);
        images.ColorDepth = ColorDepth.Depth32Bit;
        control.LargeImageList = images;
        control.HideSelection = false;
        control.SelectedIndexChanged  = control_SelectedIndexChanged;
        control.ItemSelectionChanged  = control_ItemSelectionChanged;
        control.MouseDoubleClick  = control_MouseDoubleClick;
        control.KeyDown  = control_KeyDown;
        Refresh();
        return control;
    }
    protected override void AssignDataSourceToControl(Object dataSource) {
        if(dataSource is DevExpress.Xpo.XPServerCollectionSource) {
            throw new Exception("The WinCustomListEditor doesn't support Server mode and so cannot use an XPServerCollectionSource object as the data source.");
        }
        if(controlDataSource != dataSource) {
            IBindingList oldBindable = controlDataSource as IBindingList;
            if(oldBindable != null) {
                oldBindable.ListChanged -= new ListChangedEventHandler(dataSource_ListChanged);
            }
            controlDataSource = dataSource;
            IBindingList bindable = controlDataSource as IBindingList;
            if(bindable != null) {
                bindable.ListChanged  = dataSource_ListChanged;
            }
            Refresh();
        }
    }
    public WinCustomListEditor(IModelListView info)
        : base(info) {
    }
    public override void Dispose() {
        controlDataSource = null;
        base.Dispose();
    }
    public override void Refresh() {
        if(control == null)
            return;
        object focused = FocusedObject;
        control.SelectedItems.Clear();
        try {
            control.BeginUpdate();
            images.Images.Clear();
            control.Items.Clear();
            if(ListHelper.GetList(controlDataSource) != null) {
                images.Images.Add(ImageLoader.Instance.GetImageInfo("NoImage").Image);
                foreach(IPictureItem item in ListHelper.GetList(controlDataSource)) {
                    int imageIndex = 0;
                    if(item.Image != null) {
                        images.Images.Add(item.Image);
                        imageIndex = images.Images.Count - 1;
                    }
                    System.Windows.Forms.ListViewItem lItem =
                        new System.Windows.Forms.ListViewItem(item.Text, imageIndex);
                    lItem.Tag = item;
                    control.Items.Add(lItem);
                }
            }
        }
        finally {
            control.EndUpdate();
        }

        FocusedObject = focused;
        if(FocusedObject == null && control.Items.Count > 1) {
            FocusedObject = control.Items[0].Tag;
        }
    }
    public override IList GetSelectedObjects() {
        if(control == null)
            return new object[0] { };

        object[] result = new object[control.SelectedItems.Count];
        for(int i = 0; i < control.SelectedItems.Count; i  ) {
            result[i] = control.SelectedItems[i].Tag;
        }
        return result;
    }
    public override void SaveModel() {
    }
    public override SelectionType SelectionType {
        get { return SelectionType.Full; }
    }
    public override object FocusedObject {
        get {
            return (control != null) && (control.FocusedItem != null) ? control.FocusedItem.Tag : null;
        }
        set {
            System.Windows.Forms.ListViewItem item = FindByTag(value);
            if(item != null) {
                control.SelectedItems.Clear();

                item.Focused = true;
                item.Selected = true;
            }
        }
    }
}
相关文章

转载保留此链接,注明出处