如何在WinForms中创建用于显示其他用户控件集合的用户控件?

时间:2015-04-28 14:25:52

标签: c# winforms user-controls

我需要创建一个用户控件MyTypeListControl,以便为每个对象使用用户控件MyType实例显示类型MyTypeDisplayControl的对象集合。

所以我可以

  1. MyTypeListControl的实例添加到我的WinForm,然后
  2. 加载MyType
  3. 的集合
  4. 将其分配给MyTypeListControl的DataSource。
  5. 在结果中,它应生成并显示MyTypeDisplayControl个实例中MyTypeListControl个实例的适当数量。

    如果我需要显示属性列表 - 相当于DataGrid,其中MyType的特定字段已分配给特定的DataGrid列,但我想要将每个MyType项视为用户控件 - 比DataGrid为其提供的行具有更强大的可视化表示和功能。

    这甚至可能吗?

    I found this SO resource如何创建我的集合类型,但这只是问题解决方案的一小部分......

1 个答案:

答案 0 :(得分:1)

这很容易(如果你知道的话)并且不会像你想象的那样花费太多精力(至少对于处理少于100件物品的集合的简单实现而言)。

首先让我们创建一个MyType:

public class MyType
{
    public static MyType Empty = new MyType(String.Empty, DateTime.MinValue);

    public MyType(string myName, DateTime myBirthday)
    {
        MyName = myName;
        MyBirthday = myBirthday;
    }

    public DateTime MyBirthday { get; private set; }

    public string MyName { get; private set; }
}

接下来我们需要一个MyTypeControl:

public partial class MyTypeControl : UserControl
{
    private MyType _MyType;
    private Label labelBirthday;
    private Label labelName;
    private Label labelSeparator;

    public MyTypeControl()
    {
        InitializeComponent();
    }

    public event EventHandler MyTypeChanged;

    public MyType MyType
    {
        get { return _MyType; }
        set
        {
            if (_MyType == value)
                return;

            _MyType = value ?? MyType.Empty;
            OnMyTypeChanged(EventArgs.Empty);
        }
    }

    protected virtual void OnMyTypeChanged(EventArgs eventArgs)
    {
        UpdateVisualization();
        RaiseEvent(MyTypeChanged, eventArgs);
    }

    protected void UpdateVisualization()
    {
        SuspendLayout();

        labelName.Text = _MyType.MyName;
        labelBirthday.Text = _MyType.MyBirthday.ToString("F");
        labelBirthday.Visible = _MyType.MyBirthday != DateTime.MinValue;

        ResumeLayout();
    }

    private void InitializeComponent()
    {
        labelName = new Label();
        labelBirthday = new Label();
        labelSeparator = new Label();
        SuspendLayout();
        labelName.Dock = DockStyle.Top;
        labelName.Location = new Point(0, 0);
        labelName.TextAlign = ContentAlignment.MiddleCenter;
        labelBirthday.Dock = DockStyle.Top;
        labelBirthday.TextAlign = ContentAlignment.MiddleCenter;
        labelSeparator.BorderStyle = BorderStyle.Fixed3D;
        labelSeparator.Dock = DockStyle.Top;
        labelSeparator.Size = new Size(150, 2);
        Controls.Add(labelSeparator);
        Controls.Add(labelBirthday);
        Controls.Add(labelName);
        MinimumSize = new Size(0, 48);
        Name = "MyTypeControl";
        Size = new Size(150, 48);
        ResumeLayout(false);
    }

    private void RaiseEvent(EventHandler eventHandler, EventArgs eventArgs)
    {
        var temp = eventHandler;

        if (temp != null)
            temp(this, eventArgs);
    }
}

然后是我们神奇的名单控制:

public class MyTypeListControl : UserControl
{
    private ObservableCollection<MyType> _Items;

    public MyTypeListControl()
    {
        AutoScroll = true;
        _Items = new ObservableCollection<MyType>();
        _Items.CollectionChanged += OnItemsCollectionChanged;
    }

    public Collection<MyType> Items
    {
        get { return _Items; }
    }

    private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        UpdateVisualization();
    }

    private void UpdateVisualization()
    {
        SuspendLayout();
        Controls.Clear();

        foreach (var item in _Items)
        {
            var control = new MyTypeControl { MyType = item, Dock = DockStyle.Top };
            Controls.Add(control);
            Controls.SetChildIndex(control, 0);
        }

        ResumeLayout();
    }
}

现在只需在表单或父控件中创建列表控件,并用一些有意义的值填充它:

myTypeListControl.Items.Add(new MyType("Adam", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 40))));
myTypeListControl.Items.Add(new MyType("Eva", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 38))));