2010-06-01 51 views
1

我有一個數據源('SampleAppearanceDefinitions'),它包含一個集合('Definitions')。集合中的每個項目都有幾個屬性,包括Color,這是我在這裏感興趣的。WPF - 動態訪問XAML中集合的特定項目

我希望在XAML中將集合中特定項目的顏色顯示爲文本。我可以做到這一點就好用下面這段代碼...

Text="{Binding Source={StaticResource SampleAppearanceDefinitions}, Path=Definitions[0].Color}" 

唯一的問題是,這需要我硬編碼定義集合中的項目的索引(我在這個例子中使用0以上)。我想要做的事實上是從我當前的DataContext('AppearanceID')中的屬性中獲取該值。有人可能會想象正確的代碼看起來像這樣......

Text="{Binding Source={StaticResource SampleAppearanceDefinitions}, Path=Definitions[{Binding AppearanceID}].Color}" 

......但當然,這是錯誤的。

任何人都可以告訴我做正確的方法是什麼?僅在XAML中可能嗎?感覺應該是這樣,但我無法解決或找到如何去做。

任何幫助將不勝感激!

謝謝!

AT

回答

0

即使它可能是可能的,你最好不要做這種方式,而是在您的視圖模型或視圖的後面的代碼使用專用的財產,如果它只有一個純粹的圖形含義。

此屬性,說「CurrentAppearance」,會暴露你可以從你的XAML綁定一個顏色屬性:

Text="{Binding CurrentAppearance.Color}" 

這是更容易理解。

作爲一般性建議:避免破壞你的Xaml管道代碼:Xaml應該儘可能易讀, 特別是如果你與一個沒有編碼技能並且不想關心你管理數據的方式。此外,如果稍後您決定更改數據管理方式,則不必更改Xaml。

1

MultiBinding是你的朋友在這裏:

假設你有一個TextBlock:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding Converter="{StaticResource AppearanceIDConverter}"> 
      <Binding Source="{StaticResource SampleAppearanceDefinitions}" /> 
      <Binding Path="AppearanceID" /> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

,並定義一個MultiValueConverter返回你希望看到什麼:

public class AppearanceIDConverter : IMultiValueConverter 
{ 
    #region IMultiValueConverter Members 

    public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     List<item> items = (List<item>)values[0]; //Assuming its items in a List 
     int id = (int)values[1]; //Assuming AppearanceID is an integer 
     return items.First(i => i.ID == id).Color; //Select your item based on the appearanceID.. I used LINQ, but a foreach will work just fine as well 
    } 

    public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new System.NotImplementedException(); 
    } 

    #endregion 
} 

當然,你將需要將轉換器設置爲資源字典中的資源,就像您製作SampleAppearanceDefinitions一樣。如果可以通過代碼訪問SampleAppearanceDefinitions集合,也可以使用IValueConverter禁用多重綁定並使用常規綁定到AppearanceID;)。

希望這有助於如果您的列表是在視圖模型,而不是一個靜態資源

+0

它將如何與TwoWay綁定工作? – Pragmateek 2010-06-01 12:49:39

+0

如果您希望多個數據可用於您的價值,您可以使用MultiBinding而不是普通的Binding;對於雙向綁定,您將不得不在ConvertBack方法中提供一些邏輯。 – Arcturus 2010-06-02 06:52:56

+0

準確地說,這個實現看起來並不明顯:檢索哪個對象是集合,哪個集合以及哪個索引的邊界值是棘手的;如果它存在於多個集合中呢?轉換器需要更多的上下文:我想這個上下文可以通過ConverterParameter傳遞,但是產生的Xaml可能很重。你能提供一個簡單的實現嗎?謝謝。 – Pragmateek 2010-06-02 09:03:47

0

MultiBinding可能實際工作。我驚訝地發現,傳遞給視圖的對象實際上是一個指向模型上對象的指針,所以改變視圖中的對象(例如,在文本框中鍵入新測試)將直接影響模型對象。

這對我有效。 ConvertBack方法從不使用。

public class PropertyIdToPropertyConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (values.Length == 2) 
     { 
      var properties = values[0] as ObservableCollection<PropertyModel>; 

      if (properties != null) 
      { 
       var id = (int)values[1]; 
       return properties.Where(model => model.Id == id).FirstOrDefault(); 
      } 
     } 

     return null; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
}