【问题标题】:Binding to a dependency property of a behavior inside a child control绑定到子控件内行为的依赖属性
【发布时间】:2015-01-28 20:08:41
【问题描述】:

我有以下带有自定义依赖属性的用户控件

ThumbnailListView 用户控件

        <ListView 
            ItemsSource="{Binding}" 
            BorderThickness="0,0,0,0" 
            HorizontalAlignment="Center" 
            Background="White" 
            SelectionChanged="ListView_SelectionChanged"
            AllowDrop="True">
            <i:Interaction.Behaviors>
                <behaviors:DragDropBehavior OnDragDrop="{Binding Path=ItemDragDrop}"></behaviors:DragDropBehavior>
            </i:Interaction.Behaviors>
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource IsLastListItem}}" Value="False">
                            <Setter Property="Margin" Value="0,0,0,20"></Setter>
                        </DataTrigger>
                    </Style.Triggers>

                    <Setter Property="Background" Value="Gray"></Setter>
                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"></Setter>                      
                </Style>
            </ListView.ItemContainerStyle>

            <ListView.ItemTemplate>
                <DataTemplate>
                     <Image Source="{Binding Thumbnail, Converter={StaticResource ImageConverter}}"></Image>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

ThumbnailListView的依赖属性ItemDragDrop

    public static ICommand GetItemDragDrop(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(ItemDragDropProperty);
    }

    public static void SetItemDragDrop(DependencyObject obj, ICommand value)
    {
        obj.SetValue(ItemDragDropProperty, value);
    }

    public static DependencyProperty ItemDragDropProperty = DependencyProperty.RegisterAttached("ItemDragDrop",
        typeof(ICommand), typeof(ThumbnailListView));

    public ICommand ItemDragDrop
    {
        get
        {
            return (ICommand)GetValue(ItemDragDropProperty);
        }

        set
        {
            SetValue(ItemDragDropProperty, value);
        }
    }

NewScansView 用户控件

        <DockPanel Dock="Top">
            <ListView ItemsSource="{Binding Scans}" Width="500">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Caption}" Margin="5,0,0,0"></TextBlock>
                    </DataTemplate>
                </ListView.ItemTemplate>

                <ListView.ItemContainerStyle>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
            <Views:ThumbnailListView DataContext="{Binding SelectedItem.Pages}" ItemDragDrop="{Binding SelectedItem.DragDropCommand}" VerticalAlignment="Stretch" Width="200" />
            <Views:PageListView DataContext="{Binding SelectedItem.Pages}" VerticalAlignment="Stretch" />
        </DockPanel>

NewScansView xaml 包含一个 ThumbnailListView 控件,并将 ThumbnailListView 的依赖属性 ItemDragDrop 绑定到 SelectedItem 类中的命令。

在 ThumbnailListView 用户控件中,我有一个行为 DragDropBehavior,它具有依赖属性 OnDragDrop。

我正在尝试将 OnDragDrop 绑定到 ItemDragDrop,以便在拖放操作完成时执行 SelectedItem 类中的命令。

问题是它似乎无法找到 ThumbnailListView 上的 ItemDragDrop 属性或所选项目类的 DragDropCommand。

我想知道我做错了什么以及如何设置它?

【问题讨论】:

    标签: c# wpf xaml data-binding


    【解决方案1】:

    ThumbnailListView.DataContext 设置为SelectedItem.Pages,我非常怀疑SelectedItem.Pages 有一个名为SelectedItem.DragDropCommand 的属性。

    更改ItemDragDrop 绑定的Source 以指定它使用ThumnailListView.DataContext 以外的其他内容作为该绑定的来源。

    <DockPanel x:Name="MyDockPanel" Dock="Top">
        ...
        <Views:ThumbnailListView DataContext="{Binding SelectedItem.Pages}" 
                                 ItemDragDrop="{Binding SelectedItem.DragDropCommand, ElementName=MyDockPanel}" ... />
        ...
    </DockPanel>       
    

    您可能还必须为您的行为绑定执行相同的操作 - 更改它的源,使其指向 ThumbnailListView 而不是 ThumbnailListView.DataContext

    <i:Interaction.Behaviors>
        <behaviors:DragDropBehavior OnDragDrop="{Binding Path=ItemDragDrop, RelativeSource={RelativeSource AncestorType={x:Type local:ThumbnailListView}}}" />
    </i:Interaction.Behaviors>
    

    或者更好的是,为 Pages 创建一个 DependencyProperty,这样您就不会依赖特定的 DataContext 对象类型

    <Views:ThumbnailListView PagesDependencyProperty="{Binding SelectedItem.Pages}" ItemDragDrop="{Binding SelectedItem.DragDropCommand}" .. />
    

    或编辑您的控件,使其假定 DataContext 使用特定类型,并使用隐式 DataTemplate 始终使用此控件绘制该类型的对象(对我来说更常见):

    <ListView ItemsSource="{Binding Pages}" ...>
        <i:Interaction.Behaviors>
            <behaviors:DragDropBehavior OnDragDrop="{Binding DragDropCommand}" />
        </i:Interaction.Behaviors>
        ...
    </ListView>
    

    隐式数据模板:

    <DataTemplate DataType="{x:Type local:WhateverSelectedItemDataTypeIs}}">
        <!-- DataContext will automatically set to WhateverSelectedItemDataTypeIs -->
        <Views:ThumbnailListView /> 
    </DataTemplate>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2013-12-17
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      相关资源
      最近更新 更多