Reputation: 5459
I'm trying to build a custom control for the Windows Phone 7 platform. So far I have the property defined and it works fine if it's a simple type (like a string), but this ultimately needs to be an array. So I define my property like this:
#region Keywords
public string[] Keywords
{
get { return (string[])GetValue(KeywordsProperty); }
set { SetValue(KeywordsProperty, value); }
}
public static readonly DependencyProperty KeywordsProperty =
DependencyProperty.Register(
"Keywords",
typeof(string[]),
typeof(MyType),
new PropertyMetadata(null));
#endregion Keywords
Now I want top support binding and XAML, but I can't figure out how to set the property via XAML. Is there a better way to do this?
Upvotes: 3
Views: 4936
Reputation: 62929
Using a string[] in XAML
You can instantiate your Keywords property in XAML as follows:
<MyControl ...>
<MyControl.Keywords>
<sys:String>Happy</sys:String>
<sys:String>Sad</sys:String>
<sys:String>Angry</sys:String>
</MyControl.Keywords>
</MyControl>
Note: This assumes the namespace declaration
xmlns:sys="clr-namespace:System;assembly=mscorlib"
You can bind an ItemsControl to your Keywords as follows:
<ListBox ItemsSource="{Binding Keywords}" ...>
In this example each Keyword will show up as a separate ListBox item.
Using a string[] for this purpose in WPF is perfectly kosher, as long as the array members are guaranteed to never change (you can replace the array with a new one, but not change its elements). This is because an array has no change notification mechanism.
If your elements might change
If the elements of your Keywords array might change, you should use an ObservableCollection instead of an array. Make it a read-only CLR property (not a dependency property) and initialize it in your constructor. Then you can populate it in XAML exactly as shown above, but any changes to the collection will be immediately reflected in your UI.
I actually use my own collection classes for this which have a lot more functionality than ObservableCollection. It doesn't matter what collection class you use as long as it implements INotifyCollectionChanged.
Making the list updatable using pure XAML
You cannot update your Keywords array using a Binding. If you need to update the Keywords and want to do it entirely using XAML and bindings, you'll need to create a Keyword object class that holds the string, then put them in an ObservableCollection or similar.
IValueConverter
Another approach is to use a IValueConverter to convert a comma-separated list of strings to and from a string[], like this:
<TextBox Text="{Binding Keywords,
Converter={x:Static my:CommaSeparatedConverter.Instance}}" />
where the converter would be:
public class CommaSeparatedConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return string.Join(",", (string[])value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((string)value).Split(',');
}
}
Upvotes: 6
Reputation: 2387
You should be able to bind to a specific element of an array this way:
<Textblock Text="{Binding Keywords[0]}" />
assuming of course that Keywords is available in the current DataContext.
Upvotes: 0