DotNetNewsgroup.com  
web access to complete list of Microsoft.NET newsgroups
   home   |   control panel login   |   archive  |  
 
  carried group
academic
adonet
aspnet
aspnet.announcements
aspnet.buildingcontrols
aspnet.caching
aspnet.datagridcontrol
aspnet.mobile
aspnet.security
aspnet.webcontrols
aspnet.webservices
assignment_manager
datatools
dotnet.distributed_apps
dotnet.general
dotnet.myservices
dotnet.nternationalization
dotnet.scripting
dotnet.security
dotnet.vjsharp
dotnet.vsa
dotnet.xml
dotnetfaqs
framework
framework.clr
framework.compactframework
framework.component_services
framework.controls
framework.databinding
framework.drawing
framework.enhancements
framework.interop
framework.odbcnet
framework.performance
framework.remoting
framework.sdk
framework.setup
framework.webservices
framework.windowsforms
framework.wmi
frwk.windowsforms.designtime
lang.csharp
lang.jscript
lang.vb
lang.vb.controls
lang.vb.data
lang.vb.upgrade
lang.vc
lang.vc.libraries
  
 
start date: Thu, 9 Aug 2007 13:43:14 -0700,    posted on: microsoft.public.dotnet.framework.windowsforms.databinding        back       

Thread Index
  1    Douglas Harber
          2    Marc Gravell
                 3    Marc Gravell
          4    Tim Van Wassenhove am


DataBinding to array elements   
I've got a problem that I've been wracking my brain to try to come up with a 
solution for. Basically, I've got either some XML or an object deserialized 
from that XML which has elements that have more than one occurrence. So, for 
instance, a fragment of the XML might look like this:

<Sender>
  <Name>Test Sender</Name>
  <Address>Address Line 1</Address>
  <Address>Address Line 2</Address>
  <Address>Address Line 3</Address>
</Sender>

This would get serialized into an object that looked something like this:

public class Sender
{
    private string name;
    private string[] address;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string[] Address
    {
        get { return address; }
        set { address = value; }
    }
}

My problem is that I want to databind to either a DataSet that the XML has 
been loaded into, or to the object that was deserialized from it. Binding to 
the Name property is no problem. The Address represents a problem, though. 
The form I want to bind data on has 3 textboxes for address lines, and I'd 
like to bind each textbox to one of the address string in Address.

The first problem, of course, is that there may or may not be 3 entries in 
Address but I'm willing to stipulate that the XML schema will have 
minOccurs=3.

Which comes to the real problem. Is there anyway to databind to a specific 
element within a collection? It doesn't matter whether it's in a DataSet or 
an object. But I haven't found any way to do it yet. Unfortunately, this is 
very common pattern in the data model of the application I'm trying to 
reengineer, so I'm not going to have a lot of control over changing it. 
Currently, the application implements methods on each form to load and save 
the fields from and to an object, so each form has at least one 
LoadFieldsFromXxx and SaveFieldsToXxx method, which is a terribly 
unsatisfying way to implement them.

Any help or suggestions would be greatly appreciated.

Thanks,
Doug Harber
Date:Thu, 9 Aug 2007 13:43:14 -0700   Author:  

Re: DataBinding to array elements   
Do you control the class?

How about a simple shim through properties - i.e.

[XmlIgnore]
public string AddressLine1 { get {return Address[0];} set 
{Address[0]=value;}}
[XmlIgnore]
public string AddressLine2 { get {return Address[1];} set 
{Address[1]=value;}}

you can now databind to these, safe in the knowledge that they don't 
affect serialization.

(you'd need error handling on the index etc)
Also - I don't recomment coding against an array - a 
Collection<Address> or similar would be far more controlled:
private readonly Collection<Address> addresses = new 
Collection<Address>();
[ some combination of XmlArray etc to get the naming right ]
public Collection<Address> AddressLines {get {return addresses;}}

(note then that your setter (for instance) could .Add if necessary)

I'll see if I can find the xml-markers for serialization of the above 
(xsd.exe will be my first tool...)

Marc
Date:Fri, 10 Aug 2007 08:31:40 +0100   Author:  

Re: DataBinding to array elements   
like so (and I meant "string", not "Address"); note that I haven't 
implemented notifications against AddressLine1 etc; this could be 
done, but you'd need to work with a subclass of Collection<string>, or 
switch to BindingList<string> (which also works), and handle the 
insert/etc.

Marc

using System;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        Sender s = new Sender();
        s.Name = "Test Name";
        s.AddressLine3 = "Test 3";
        s.AddressLine1 = "Test 1";
        XmlSerializer ser = new XmlSerializer(typeof(Sender));
        ser.Serialize(Console.Out, s);
    }
}

[Serializable]
public sealed class Sender : INotifyPropertyChanged
{
    [XmlIgnore]
    public string AddressLine1 {
        get { return GetAddressLine(0); }
        set { SetAddressLine(0,value); }
    }
    [XmlIgnore]
    public string AddressLine2
    {
        get { return GetAddressLine(1); }
        set { SetAddressLine(1,value); }
    }
    [XmlIgnore]
    public string AddressLine3
    {
        get { return GetAddressLine(2); }
        set { SetAddressLine(2,value); }
    }
    public string GetAddressLine(int index)
    {
        return AddressLines.Count > index ? AddressLines[index] : "";
    }
    public void SetAddressLine(int index, string value)
    {
        while (AddressLines.Count <= index)
        {
            AddressLines.Add("");
        }
        AddressLines[index] = value;
    }

    string name;
    public string Name { get { return name; } set {SetField(ref name, 
value, "Name");}}

    readonly Collection<string> addressLines = new 
Collection<string>();
    [XmlElement("Address")]
    public Collection<string> AddressLines {get {return 
addressLines;}}

    public event PropertyChangedEventHandler PropertyChanged;

    private void SetField<T>(ref T field, T value, string 
propertyName) {
        if(EqualityComparer<T>.Default.Equals(field,value)) return; // 
no change
        field = value;
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Date:Fri, 10 Aug 2007 09:14:05 +0100   Author:  

Re: DataBinding to array elements   
On 2007-08-09, Douglas Harber  wrote:

> Which comes to the real problem. Is there anyway to databind to a specific 
> element within a collection? It doesn't matter whether it's in a DataSet or 
> an object. But I haven't found any way to do it yet. Unfortunately, this is 
> very common pattern in the data model of the application I'm trying to 
> reengineer, so I'm not going to have a lot of control over changing it. 


Instead of manually creating 'shim' properties, you could also implement
ICustomTypeDescriptor and expose each element via the GetProperties
implementation.

-- 
Kind regards,
Tim Van Wassenhove <url:http://www.timvw.be/>
Date:Wed, 15 Aug 2007 00:04:04 -0700   Author:  

Google
 
Web dotnetnewsgroup.com


COPYRIGHT ?2005, EUROFRONT WORLDWIDE LTD., ALL RIGHT RESERVE  |   Contact us