Binding.FormatString rendering curly braces & trick to Bind to List<T>.Countproperty?

S

Steve K

First problem:
I am specifying a format string for a Binding object like so:
<code>
Binding binding = new Binding("Text",
item.EOBRemittance,
"AmountAllowed",
true,
DataSourceUpdateMode.Never,
0,
"{0} Selected Pages");
</code>

When I run my application the Format string is working 50% ;0)

Instead of: "20 Selected Pages"
I see: "{20} Selected Pages"

So it's dropping the bound property's value in the right place, but it's
not removing the '{' and '}' characters. Does this seem like a bug or
am I doing something wrong?

Second problem:

I have a somewhat interesting situation where I would like to bind a
LinkLabel's Text property to the Count property on a List<T>. I know
List<T>.Count is readonly, but I thought you could still one-way bind to
a read only property?

Here is the code:
<code>
Binding binding = new Binding("Text",
item.AttachmentIndices,
"Count",
true,
DataSourceUpdateMode.Never,
0,
"{0} Selected Pages");

_linkLabel_SelectPages.DataBindings.Clear();
_linkLabel_SelectPages.DataBindings.Add(binding);
</code>

In the above example item.AttachmentIndices is a List<int>.


When I run my application, I get the following exception:
"Cannot bind to the property or column Count on the DataSource"

I tried the same with the Capacity property and it threw the same error,
however it is read/write. So maybe I'm barking up the wrong tree?

I look through reflector and (Couldn't find List<T> but checked some
other classes) and didn't see any special attributes or anything.

Anyone have any ideas?
 
M

Marc Gravell

I'm surprised the first scenario worked *at all*; I'll have a look...

Re the second - you can't bind to properties of anything that implements
IList or IListSource; it assmumes you mean "get the currency-manager for
that collection, lookup the item at the current cursor position, and
find the named property on that item". If you aren't doing anything else
with the collection, this is equivalent to looking at list[0].Count,
which is unlikely to exist.

Marc
 
M

Marc Gravell

To do the custom formatting:

Binding binding = new Binding("Text", source, "PropName",true);
binding.Format += delegate(object sender, ConvertEventArgs args)
{
args.Value = string.Format("{0} items", args.Value);
};

Marc
 
S

Steve K

Marc said:
To do the custom formatting:

Binding binding = new Binding("Text", source, "PropName",true);
binding.Format += delegate(object sender, ConvertEventArgs args)
{
args.Value = string.Format("{0} items", args.Value);
};

Marc
Nice use of anonymous delegate, thanks for the snippet, Marc!
 
S

Steve K

Marc said:
I'm surprised the first scenario worked *at all*; I'll have a look...

Re the second - you can't bind to properties of anything that implements
IList or IListSource; it assmumes you mean "get the currency-manager for
that collection, lookup the item at the current cursor position, and
find the named property on that item". If you aren't doing anything else
with the collection, this is equivalent to looking at list[0].Count,
which is unlikely to exist.

Marc
I didn't know that, I thought we could bind to *any* public property,
regardless of what interfaces it's class implements. This seems a bit
presumptuous of the framework to assume that I want one thing went I've
clearly set it up to use the "Count" property.

I'm bummed, this would have saved me several function calls and
concurrency issues with keeping my View up to date with my Model.

The only other semi-automatic solution I can come up with is to use a
collection that raises change notifications and wire those up to my View
method that updates the count control.

If you have any other suggestions I would dig hearing em' ;0)

Thanks for the explanation,
Steve
 
M

Marc Gravell

Well, depending on the setup, you could facade the count into the
containing class - i.e.

class Foo {
public List<Bar> Bars {get {...}}

public int BarCount {get {return Bars.Count;}}
}

Now you can bind to a Foo, looking at "BarCount", and "Bars.SomeProp"
to get the SomeProp from the selected "Bar". If you explain the setup
more, there may be other options...

Marc
 
S

Steve K

Marc said:
Well, depending on the setup, you could facade the count into the
containing class - i.e.

class Foo {
public List<Bar> Bars {get {...}}

public int BarCount {get {return Bars.Count;}}
}

The facade solution is so simple and in my case a perfect solution. I
overlooked it somehow, thanks for pointing it out.

Have a great weekend,
Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top