Announcement

Collapse
No announcement yet.

Bindings

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bindings

    Hallo wollte eine Collection erstellen, welche ich direkt einem GridView als DataSource zuweisen kann. Das ganze funktioniert auch sehr gut und wird
    momentan ungefähr so gemacht:

    public partial class UserCollection : System.Collections.CollectionBase, ITypedList
    {

    #region ITypedList Members
    PropertyDescriptorCollection propertyDescriptorCollection = new PropertyDescriptorCollection(null);


    public PropertyDescriptorCollection PropertyDescriptorCollection
    { get { return propertyDescriptorCollection; } }

    public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
    { return this.propertyDescriptorCollection; }

    public string GetListName(PropertyDescriptor[] listAccessors)
    { return "UserCollection"; }

    #endregion

    ... und noch andere Dinge
    }


    Der Eigenschaft PropertyDescriptorCollection kann ich auch sehr gut spezialisierte PropertyDescriptoren zuweisen, welche alle von der
    Klasse AbstractPropertyDescriptor abgeleitet sind. Wenn die Daten nun
    in meiner Collection drin sind, kann ich über :

    userCollection.PropertyDescriptorCollection.Add(ne w PhoneProperty());
    userCollection.PropertyDescriptorCollection.Add(ne w EmailProperty());
    userCollection.PropertyDescriptorCollection.Add(ne w NameProperty());

    und so weiter die einzelnen Spalten bestimmen, welche ich in dem Grid
    sehen will. Nun weise ich einfach über "gridView.DataSource = userCollection"
    die Daten dem Grid zu und ich sehe auch die drei Spalten wie angegeben.


    Nun will ich aber die gleichen Daten einem zweiten GridView zuweisen. Hier
    möchte ich aber andere Spalten sehen. Ich möchte also eine andere Sicht
    auf die Daten.

    Wie bekommt man es hin, das die "Erste Sicht" unabhängig von der "Zweiten Sicht" ist, die Daten aber nur einmal vorhanden sind? Gibt es dafür ein Vorgehen?

    Diese Trennung Bekomme ich auf diesen Weg hin.

    userCollection.PropertyDescriptorCollection.Clear( );
    userCollection.PropertyDescriptorCollection.Add(ne w MaleProperty());
    userCollection.PropertyDescriptorCollection.Add(ne w StreetlProperty());
    userCollection.PropertyDescriptorCollection.Add(ne w PhoneProperty());
    BindingSource bindingSource = new BindingSource();
    bindingSource.ResetBindings(true);
    bindingSource.DataSource = dmsMailbox.Collection;
    gridView.DataSource = bindingSource;

    Hat das schon einmal jemand ähnlich gemacht oder ist dieses
    vorgehen ein absolutes "NoGo"?

    Danke, Dieter

  • #2
    Hallo Dieter,

    wenn ich die Aufgabe richtig verstanden habe dann gehts du einen unkonventionelle Weg.

    Ich würde das mit List<> und LINQ lösen -> zB
    [highlight=c#]
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    //---------------------------------------------------------------------
    /// <summary>
    /// Daten für DataGridView1 laden
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
    var data1 =
    (from u in UserCollection.userCollection
    select new
    {
    Phone = u.Phone,
    Email = u.Email,
    Name = u.Name
    }).ToList();

    dataGridView1.DataSource = data1;
    }
    //---------------------------------------------------------------------
    /// <summary>
    /// Daten für DataGridView2 laden
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, EventArgs e)
    {
    var data2 =
    (from u in UserCollection.userCollection
    select new
    {
    Male = u.Male,
    Street = u.Street,
    Phone = u.Phone
    }).ToList();

    dataGridView2.DataSource = data2;
    }
    }
    //-------------------------------------------------------------------------
    /// <summary>
    /// Klasse mit Eigenschaften für User (Automatic Properties)
    /// </summary>
    public class User
    {
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public bool Male { get; set; }
    public string Street { get; set; }
    }
    //-------------------------------------------------------------------------
    /// <summary>
    /// Generische Liste mit den Usern -> UserCollection.
    /// </summary>
    /// <remarks>
    /// Weitere Infos unter:
    /// http://weblogs.asp.net/scottgu/archi...tializers.aspx
    /// </remarks>
    public static class UserCollection
    {
    public static List<User> userCollection = new List<User>
    {
    new User
    {
    Email = "[email protected]",
    Male = true,
    Name = "abc",
    Phone = "+43 123 123",
    Street = "Strasse Nr. 1"
    },
    new User
    {
    Email = "[email protected]",
    Male = false,
    Name = "xyz",
    Phone = "+43 666 666",
    Street = "Strasse Nr. 69"
    },
    };
    }
    }
    [/highlight]

    Wichtig ist dass nach der LINQ-Abfrage mit ToList() die Abfrage auch ausgeführt wird, ansonsten erstellt LINQ nur die Abfrage - führt sie aber nicht aus (glaube das heißt deffered loading/execution).

    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Super

      Hallo gfoidl,

      das funktioniert ja wunderbar. Ich habe nur noch ein problem mit den PropertyDescriptoren. Können diese in einem solchen Zusammenhang auch verwendet werden. Über meine PropertyDescriptoren steuere ich beispielsweise
      den Anzeigenamen (DisplayName) für einzelne Spalten.

      Gruß, Dieter

      Comment


      • #4
        Hallo Dieter,

        sorry für späte Rückmeldung (hatte gestern keine Zeit).

        Grundsätzlich entspricht der Spaltenname dem Eigenschaftsbezeichner der gebundenen Spalte.

        Dieser angezeigte Name kann nachträglich geändert werden mit
        [highlight=c#]
        // über Spaltennamen:
        dataGridView1.Columns["Phone"].HeaderText = "Telefon";

        // oder über Spaltenindex:
        dataGridView1.Columns[0].HeaderText = "Telefon";
        [/highlight]

        Habe ich dich richtig verstanden? Sonst bitte melden.

        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment

        Working...
        X