[英]How do I provide a collection of elements to a custom attached property?
我在网上找到了一些示例,并在此处找到了一些问题和答案,但我无法使其正常工作。 我需要一个可以包含一个或多个目标元素的自定义附加属性。 例如...
<ListView>
<dd:MyDragDrop.DropBorders>
<Binding ElementName="brdOne"/>
<Binding ElementName="brdTwo"/>
<Binding ElementName="brdThree"/>
</dd:MyDragDrop.DropBorders>
</ListView>
我也曾尝试过使用MultiBinding,但是没有运气。
<ListView>
<dd:MyDragDrop.DropBorders>
<MultiBinding Converter="{StaticResource multi}">
<Binding ElementName="brdOne"/>
<Binding ElementName="brdTwo"/>
<Binding ElementName="brdThree"/>
</MultiBinding>
</dd:MyDragDrop.DropBorders>
</ListView>
有空的时候我会再详细说明,但与此同时..是否有“正确”的方式来做到这一点? 感觉应该比我做的要简单!
仅供参考,这是我正在玩的附加物业。 现在完全是一个实验,因此根本不需要完善,很大程度上是尝试使用来自不同在线解决方案的不同解决方案的结果。
public class BorderCollection : List<Border>
{
}
public static readonly DependencyProperty DropBordersProperty = DependencyProperty.RegisterAttached("DropBorders", typeof(BorderCollection), typeof(MyDragDrop));
public static BorderCollection GetDropBorders(ListView listView)
{
var collection = (BorderCollection)listView.GetValue(DropBordersProperty);
if (collection == null)
{
collection = new BorderCollection();
listView.SetValue(DropBordersProperty, collection);
}
return collection;
}
public static void SetDropBorders(ListView listView, BorderCollection borders)
{
listView.SetValue(DropBordersProperty, borders);
foreach (Border border in borders)
{
border.Background = new SolidColorBrush(Colors.Green);
}
}
谢谢。
您应该能够执行以下操作:
<ListView>
<dd:MyDragDrop.DropBorders>
<Border Style="{StaticResource brdOneStyle}"/>
<Border Style="{StaticResource brdTwoStyle}"/>
<Border Style="{StaticResource brdThreeStyle}"/>
</dd:MyDragDrop.DropBorders>
</ListView>
我不建议您使用绑定来指定DropBorders,因为Border是UIElement,而UIElement在视觉树中只能出现一次。 如果使用相同的Border元素实例具有多个listview,则可能会出现运行时错误。 如果要重用边框,请改用样式。
我设法使用IMultiValueConverter
使其正常工作:
public class BorderCollectionConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var borderCollection = new BorderCollection();
borderCollection.AddRange(values.OfType<Border>());
return borderCollection;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
就像您的示例一样,在XAML中使用它:
<Border Height="20" Name="border1" Background="Blue" />
<Border Height="20" Name="border2" Background="Green" />
<Border Height="20" Name="border3" Background="Yellow" />
<Control>
<dd:MyDragDrop.DropBorders>
<MultiBinding Converter="{StaticResource borderCollectionConverter}">
<Binding ElementName="border1" />
<Binding ElementName="border3" />
</MultiBinding>
</dd:MyDragDrop.DropBorders>
</Control>
主要区别在于如何使用问题注释中给出的建议来声明DependencyProperty
(getter或setter中没有代码,而使用元数据来定义属性更改的回调):
public static readonly DependencyProperty DropBordersProperty =
DependencyProperty.RegisterAttached("DropBorders", typeof(BorderCollection), typeof(MyDragDrop),
new PropertyMetadata(null, DropBordersChanged));
public static BorderCollection GetDropBorders(DependencyObject listView)
{
return (BorderCollection)listView.GetValue(DropBordersProperty);
}
public static void SetDropBorders(DependencyObject listView, BorderCollection borders)
{
listView.SetValue(DropBordersProperty, borders);
}
public static void DropBordersChanged(object sender, DependencyPropertyChangedEventArgs e)
{
foreach (var border in (BorderCollection)e.NewValue)
border.Background = new SolidColorBrush(Colors.Red);
}
最后的结果
BorderCollection
是Border
元素的List
,但是,您尝试使用Binding
元素的集合。
<dd:MyDragDrop.DropBorders>
<Binding ElementName="brdOne"/>
<Binding ElementName="brdTwo"/>
<Binding ElementName="brdThree"/>
</dd:MyDragDrop.DropBorders>
请记住, Binding
元素不是 Border
元素。 您的DropBorders
集合需要Border
列表。 像这样:
<dd:MyDragDrop.DropBorders>
<Border ... />
...
</dd:MyDragDrop.DropBorders>
考虑将BorderCollection
更改为继承List<Binding>
。 然后,您可以使用绑定集合来获取集合中的边框。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.