如何为自定义附加属性提供元素集合?

时间:2015-06-22 06:53:09

标签: c# wpf binding

我在网上找到了一些例子,这里有一些问题和答案,但我无法让它发挥作用。我需要一个可以带一个或多个目标元素的自定义附加属性。例如......

<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);
    }
}

感谢。

3 个答案:

答案 0 :(得分:1)

您应该可以执行以下操作:

-(void) startAutocomplete{
    NSString* baseUrl = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input=%@&key=AIzaSyDz3HAmNY8NsgIhtA8gtbH-QA08Lg9tej4&types=all", self.locationTextfield.text];

    NSURL *url = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"Url: %@", url);
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        if (connectionError!=nil) {
            [[[UIAlertView alloc] initWithTitle:nil message:connectionError.localizedDescription delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil] show ] ;
        }else{
            NSError *error = nil;
            self.searchResult= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

            //NSLog(@"result:%@",self.searchResult);
            [self.tableView reloadData];
        }

    }];
}

我建议您不要使用绑定指定DropBorders,因为Border是UIElement而UIElement只能在可视树中使用一次。如果您使用相同的Border元素实例有多个listview,则可能会出现运行时错误。如果要重复使用边框,请改用样式。

答案 1 :(得分:1)

我设法使用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);
}

最后的结果......

Example showing two Borders with red background and one with green background

答案 2 :(得分:0)

您的BorderCollectionList Border个元素,但是,您尝试使用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>。然后,您可以使用您的绑定集合来获取集合中的边框。