编辑这太疯狂了,请不要尝试。
这并不适合胆小的人,但一种可能性是使用运行时类型系统来实现自定义属性。您可以定制一个自定义类型来公开您想要的属性,同时仍然在内部维护一个可见性列表。使用像这样的简单属性:
<Button Visibility="{Binding Visibilities.V1}" />
<Button Visibility="{Binding Visibilities.V2}" />
然后您会希望您的“Visibilities”对象实现一个实现“ICustomTypeProvider”的类,包装适当的数据(Visibility 的数组)。它还应该为基础值公开一个索引器,并且 setter 应该引发“PropertyChanged”:
public class VisibilitiesClass : ICustomTypeProvider, INotifyPropertyChanged
{
public Visibility[] Visibilities { get; private set; };
public VisibilitiesClass(int count)
{
Visibilities = new Visibility[count];
for (int i = 0; i < count; i++)
Visibilities[i] = Visibility.Collapsed;
}
public Type GetCustomType()
{
return new VisibilitiesType(Visibilities.Length);
}
public Visibility this[int index]
{
get { return Visibilities[index]; }
set
{
Visibilities[index] = value;
RaisePropertyChanged("V" + index);
}
}
}
上面引用的VisibilitiesType 应该扩展Type,并且会根据需要返回属性列表(“V1”、“V2”、...、“Vn”):
public class VisibilitiesType : Type
{
private int _count;
public VisibilitiesType(int count)
{
_count = count;
}
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return Enumerable.Range(1, _count).Select(i => new VisibilityProperty(i)).ToArray();
}
}
最后,“VisibilityProperty”应该扩展“PropertyInfo”,并从宿主对象返回适当的值:
public class VisibilityProperty : PropertyInfo
{
private int _index;
public VisibilityProperty(int index)
{
_index = index;
}
public override string Name
{
get { return "V" + _index; }
}
public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
{
var host = obj as VisibilitiesClass;
return host[_index];
}
}
请注意,上面的实现非常省略 - “Type”和“PropertyInfo”都有大量虚拟方法,其中一些您可能需要覆盖。