2010-02-18 61 views
0

我想知道如何通过调用可用作该属性的“数据提供者”的方法来设置自定义用户控件的自定义属性。如何通过调用方法设置属性

我的意思是我想写的东西是这样的:

<CatsUserControl Cats={FindAllCats} />

其中CatsUserControl是用户控制我创建(其中有一个属性命名),和FindAllCats()是用C#编写的方法,它返回一个Cat对象列表。

这可能吗?

我很欣赏任何想法。谢谢!

编辑:

整个事情开始,因为我希望能够到一个列表分配给XAML的属性,你做<Button Content="Value"/>(以同样的方式,除了在我的情况下,该值是一个更复杂类型比字符串,这是一个List<KeyValuePair<String, Boolean>>)。

因为我没有找到任何方法来做到这一点,我认为可能会调用一个方法返回这个列表,并将返回的值赋给属性。

希望让事情更清楚。

+0

“FindAllCats是一种方法”,罚款,但在什么情况下。它是'CatsUserControl'上的方法吗?或者它是当前DataContext的对象上的方法,还是它的某种类型的StaticMethod或...列表继续。请澄清一下,你的编辑没有清除这个。 – AnthonyWJones 2010-02-18 21:32:39

+0

我一直在努力的一件事就是为什么任何人都希望有一个“FindAllCats”方法而不是“AllCats”属性。如果你有一个简单的绑定AllCats属性。那么__why__是否以FindAllCats的形式实现AllCats? (我明白,这个例子代码,但原则成立)。 – AnthonyWJones 2010-02-18 21:38:54

+0

@AnthonyWJones:结果我所需要的只是一个简单的约束。事情是,我想将AllCats属性绑定到FindAllCats方法的返回值。我想这样做是因为“AllCats”属性是在另一个用户控件(UC2)中在XAML中创建的UserControl(UC1)的属性,创建UC1的每个UC2都有其自己的FindAllCats方法。我很抱歉发生混淆,并花了很长时间才发表回复。 – dsetton 2010-02-26 19:45:54

回答

2

这似乎是你想要做的只是数据绑定?

换句话说,你将接近这样的:

<CatsUserControl ItemsSource="{Binding AllCats}" /> 

Binding to a collection

如果你想特异性结合到一个叫猫,你需要创建一个实现INotifyPropertyChanged的对象属性,我觉得。 (半伪代码如下):

//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)); 
     } 
    } 
} 

,然后绑定到它与您的自定义用户控件:

<CatsUserControl Cats="{Binding AllCats, Source={StaticResource BindingToCats}}" /> 
+0

不,这不是我所需要的。我编辑了我的问题以更好地描述我所追求的内容。对不起,如果我以前不清楚。 – dsetton 2010-02-18 19:05:37

+0

INotifyPropertyChanged实现仅在需要UI来跟踪对属性所做的更改时才有必要。这是一个相当普遍的要求,但并不是完成绑定工作所必需的。在属性值是只读或固定的情况下,一旦对象被初始化,INotifyPropertyChanged不需要。 – AnthonyWJones 2010-02-18 21:29:43

+0

@AnthonyWJones - 好点... – 2010-02-19 17:26:51

0

你应该能够做到你的要求通过订阅事件,而不是直接从XAML绑定。

此外,你可以使用一个转换器,其描述here

+0

事件的想法很好,但我想在XAML中设置所有控件的属性,所以清楚这些值来自哪里。转换器OTOH是一个很好的解决方案。 – dsetton 2010-02-26 22:32:50

1

您可能正在寻找的是TypeConverter

下面是如何设置列表的示例< KeyValuePair < String,Boolean >>在xaml中使用属性语法中的字符串。 Xaml最终会看起来像这样:

<c:CustomButton Values="Hello World,true; Foo,false; Bar,true" /> 

您想要表示键/值对列表的确切语法取决于您。

这里是要做到这一点所需的代码:

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); 
    } 
} 
+0

我喜欢你的解决方案!不仅因为它适用于我的情况,还因为它让我意识到XAML中的值不必局限于字符串。我的意思是,即使“Hello World,真的;富,假的;酒吧,真”是一个字符串,它代表一个整体的其他类型,我可以将它转换为可能性是无穷的:!d由于太糟糕了,我不能标记两个答案为正确.. – dsetton 2010-02-26 22:27:27

相关问题