2010-02-18 89 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