How to set a property by calling a method
I'd like to know how to set a custom property of a custom user control by calling a method that would serve as "data provider" for that 开发者_Go百科property.
What I mean is I'd like to write something like this:
<CatsUserControl Cats={FindAllCats} />
,
where CatsUserControl is a User Control I created (which has a Property named Cats), and FindAllCats() is a method written in C# that returns a list of Cat objects.
Is this possible?
I appreciate any ideas. Thanks!
EDIT:
The whole thing began because I wanted to be able to assign a list to a property in XAML, the same way you do <Button Content="Value"/>
(except, in my case, Value is a more complex type than a string, it's a List<KeyValuePair<String, Boolean>>
).
Hope that makes things clearer.
It seems like what you are trying to do is really just databinding?
In other words, you would approach it like this:
<CatsUserControl ItemsSource="{Binding AllCats}" />
Binding to a collection
If you want to bind specifically to a property called Cats you need to create an object that implements INotifyPropertyChanged, I think. (semi-pseudo code follows):
//binding to this public property in the CatsUserControl
public List<Cat> Cats;
public class BindingToCats : INotifyPropertyChanged
{
private List<Cat> allCats;
public List<Cat> AllCats
{
get { return allCats; }
set
{
allCats = value;
OnPropertyChanged("AllCats");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
and then bind to it with your custom usercontrol:
<CatsUserControl Cats="{Binding AllCats, Source={StaticResource BindingToCats}}" />
What you are probably looking for is a TypeConverter.
Here is an example of how you can set a List< KeyValuePair< String, Boolean>> using a string in attribute syntax in xaml. The Xaml will end up looking something like:
<c:CustomButton Values="Hello World,true; Foo,false; Bar,true" />
The exact syntax of how you want to represent the list of key/value pairs is up to you.
Here is the code necessary to do this:
public class CustomButton : Button
{
[TypeConverter(typeof(ListOfStringAndBoolPairsTypeConverter))]
public List<KeyValuePair<String, Boolean>> Values { get; set; }
}
public class ListOfStringAndBoolPairsTypeConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
//TODO: Should add better error handling here.
var stringValue = (string)value;
var pairs = stringValue.Split(';').Select(ps => ParsePair(ps));
var result = new List<KeyValuePair<String, Boolean>>();
result.AddRange(pairs);
return result;
}
private KeyValuePair<String, Boolean> ParsePair(string pairStringValue)
{
var splitString = pairStringValue.Split(',');
var key = splitString[0];
var value = Boolean.Parse(splitString[1].Trim());
return new KeyValuePair<string, bool>(key, value);
}
}
You ought to be able to do what you're asking by subscribing to events instead of binding directly from the XAML.
Also, you could use a converter, which is described here.
精彩评论