一種可能的解決方案是,而不是使用簡單的集合作爲內部對象,創建從集合派生的類和執行它ICustomTypeDescriptor
。在接口實現中,遍歷集合的元素並相應地填充屬性描述符集合。一旦你這樣做,你應該能夠綁定到來自XAML的這些屬性。
實施例 - 基於字典,它可以綁定針對其鍵名(I壓縮到單一線的所有瑣碎方法的實施方式)中的數據對象:
class DictionaryDataObject : Dictionary<string, object>, ICustomTypeDescriptor
{
#region ICustomTypeDescriptor Members
public AttributeCollection GetAttributes() { return AttributeCollection.Empty; }
public string GetClassName() { return "DictionaryDataObject"; }
public string GetComponentName() { return null; }
public TypeConverter GetConverter() { return null; }
public EventDescriptor GetDefaultEvent() { return null; }
public PropertyDescriptor GetDefaultProperty() { return null; }
public object GetEditor(Type editorBaseType) { return null; }
public EventDescriptorCollection GetEvents(Attribute[] attributes) { return EventDescriptorCollection.Empty; }
public EventDescriptorCollection GetEvents() { return EventDescriptorCollection.Empty; }
public PropertyDescriptorCollection GetProperties() { return GetProperties(null); }
public object GetPropertyOwner(PropertyDescriptor pd) { return this; }
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var pds =
this.Keys
.Select(x => new DictionaryPropertyDescriptor(x))
.ToArray();
return new PropertyDescriptorCollection(pds);
}
#endregion
}
class DictionaryPropertyDescriptor : PropertyDescriptor
{
public DictionaryPropertyDescriptor(string name) : base(name, null) { }
public override bool CanResetValue(object component) { return false; }
public override Type ComponentType { get { return null; } }
public override bool IsReadOnly { get { return false; } }
public override Type PropertyType { get { return typeof(object); } }
public override void ResetValue(object component) { }
public override bool ShouldSerializeValue(object component) { return false; }
public override object GetValue(object component)
{
var dic = component as DictionaryDataObject;
if (dic == null) return null;
return dic[Name];
}
public override void SetValue(object component, object value)
{
var dic = component as DictionaryDataObject;
if (dic == null) return;
dic[Name] = value;
}
}
樣品物體設置從後面的代碼:
DictionaryDataObject ddo = new DictionaryDataObject();
public Window4()
{
ddo["propa"] = 1;
ddo["propb"] = "foo";
ddo["propc"] = "bar";
ddo["propd"] = 4.5;
InitializeComponent();
DataContext = ddo;
}
XAML用法:
<Window.Resources>
<DataTemplate x:Key="template">
<WrapPanel>
<TextBlock Text="{Binding propa}" Margin="5"/>
<TextBlock Text="{Binding propb}" Margin="5"/>
<TextBlock Text="{Binding propc}" Margin="5"/>
<TextBlock Text="{Binding propd}" Margin="5"/>
</WrapPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource template}"/>
</Grid>
如果你想ADAP將此解決方案轉換爲列表而不是字典,則必須根據list元素的某些屬性設置每個屬性名稱。
我已經閱讀過,您的解決方案看起來確實很優雅。我沒有意識到你可以綁定到一個集合(就像你在模板字符串中做的那樣)。即Text ='{{Binding Periods [{0}]。{1}}}' 我認爲這僅限於WPF,Silverlight無法做到這一點。我會進一步調查。謝謝! – 2010-03-10 09:06:08