views:

481

answers:

1

I feel like I've missed something obvious, but when creating a custom control in Silverlight I can declare properties as public and they will be exposed when making XAML declarations, so I can easily do something like this:

public class MyControl : UserControl
{
    public string Title {get; set;}
}

And this:

<local:MyControl Title="Hello World" />

However properties are not always simple types, I may have a complex property, like a list that defines 1 or more columns and identifies a field to be bound to it. With existing controls the syntax for defining these values in XAML is straight forward:

<local:MyControl Title="People List">
   <local:MyControl.Columns>
      <local:MyControlColumn Heading="Column 1" Binding="{Binding Name}" />
      <local:MyControlColumn Heading="Column 2" Binding="{Binding Age}" />
   </local:MyControl.Columns>
</local:MyControl>

However I'm at a loss of how to make this work in the class definition:

public class MyControl : UserControl
{
    public string Title {get; set;}
    public IEnumerable ItemSource {get; set;}
    public ObservableCollection<MyControlColumn> Columns {get; set;} // ?
}

public class MyControlColumn
{
    public string Heading {get; set;}
    public ??? Binding {get; set;} // ?
}

Can anyone point me in the right direction for making exposed list and binding properties?

+1  A: 

For the Columns collection create a backing private variable to hold an instance collection and remove the set accessor:-

private ObservableCollection<MyControlColumn> _columns = new ObservableCollection<MyControlColumn>();
public ObservableCollection<MyControlColumn> Columns {get { return _columns; } }

For the Binding property it looks like what you might want is the Binding type itself System.Windows.Data.Binding. However I think I'd need to know a little more about what you intend to do with the object once you've got it.

You should consider making the MyControl Title property a DependencyProperty:-

public string Title
{
 get { return (string)GetValue(TitleProperty); }
 set { SetValue(TitleProperty, value); }
}

public static readonly DependencyProperty TitleProperty =
  DependencyProperty.Register("Title", typeof(string), typeof(MyControl), null);

Similarly for the ItemSource although you should also rename to ItemsSource to keep convention with existing controls.

I can't help feel there is some re-invention of the wheel here, does DataGrid or ListBox or some other similar control not cut it for you?

AnthonyWJones
That does describe what I'm doing - I actually need a control that acts like a heavily customized DataGrid *or* ListBox based on setting. I plan on having my class simply wrap and reuse these controls, but since the values provided won't directly in those controls (and I don't want to expose all their attributes) I can't just inherit from one of them.
David