开发者

Binding a ListBox to an interface's properties in Silverlight

I'm having issues getting my databinding working for a ListBox. I suspect it's because I'm trying to databind against an interface rather than a class.

My C# code:

namespace MyNamespace
{
    interface IFoo
    {
        string Bar { get; }
    }

    class Fizz
    {
        private class Buzz : IFoo
        {
            public string Bar { get { return "something"; } }
        }

        public IEnumerable<IFoo> GetFoo()
        {
            List<Buzz> items = new List<Buzz>();
            // Populate items
            return items;
        }
    }
}

When I try to do databinding with the output from Fizz::GetFoo(), it doesn't work. My XAML looks like:

<ListBox Name="listBox1" ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                 <TextBlock 开发者_开发知识库Text="Bar:" />
                 <TextBlock Text="{Binding Bar}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

When I run it, I see the text for the first TextBlock but not the second. I see errors in the Output window similar to this:

    System.Windows.Data Error: Cannot get 'Bar' value (type 'System.String') from 'Buzz' (type 'MyNamespace.Fizz+Buzz'). BindingExpression: Path='Bar' DataItem='Buzz' (HashCode=100433959); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String').. System.MethodAccessException: Attempt to access the method failed: MyNamespace.Fizz+Buzz.get_Bar()
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.InternalGetValue(PropertyInfo thisProperty, Object obj, Object[] index, StacA first chance exception of type 'System.MethodAccessException' occurred in mscorlib.dll

Am I doing something wrong or is what I'm trying to do just not possible?


It looks like everything in your chain needs to be public (and your List needs to be List<IFoo> instead of List<Bar>):

public interface IFoo
{
    string Bar { get; }
}

public class Fizz
{
    public class Buzz : IFoo
    {
        public string Bar { get { return "something"; } }
    }

    public IEnumerable<IFoo> GetFoo()
    {
        List<IFoo> items = new List<IFoo>();
        // Populate items
        return items;
    }
}

The problem you are running into has to do with reflection across assemblies. The Silverlight code is reflecting on your internal class and interface (classes and interfaces are internal unless otherwise specified). Even Buzz needs to be public because it still needs to reflect upon that class, which is private, so it fails.

Obviously, if you were not using data binding here, the code would work fine. You would have access to IFoo even though Buzz is private. But, once you bring reflection into the mix, you have to start making things public, unfortunately.


The problem is that your Buzz class is private, and so the binding engine cannot access the members of that class to perform binding on.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜