开发者

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>>).

Because I didn't find any way to do that, I thought it might be possible to call a method that returns this list and assign the returned value to the property instead.

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.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜