为什么这个绑定不起作用

时间:2012-07-05 12:30:33

标签: wpf xaml data-binding attachedbehaviors

我有一个第三方SplitButton控件,它公开一些DropDownContent和一个布尔IsOpen dp来控制是否显示下拉内容。

在DropDownContent是具有多个按钮的StackPanel的情况下,每个按钮都绑定到视图模型中的命令。除了执行该命令之外,单击该按钮需要关闭打开的DropDown内容,我正在使用下面的AttachedBehavior。

但我的绑定,简单需要获取对祖先SplitButton控件的引用不起作用。在绑定中,您将注意到我正在尝试查找SplitButton类型的第一个Ancestor控件。但我确实看到调试信息表示祖先级别1,所以我将级别更改为高达4,但仍然有错误。

有人能看到修复的内容吗?

绑定错误

  

System.Windows.Data错误:4:找不到带引用的绑定源    'RelativeSource FindAncestor,AncestorType ='Xceed.Wpf.Toolkit.SplitButton',    AncestorLevel = '1'”。 BindingExpression :(没有路径);的DataItem = NULL;目标元素是    'CloseDropDownContentBehavior'(HashCode = 8896066); target属性是'DropDownButtonElement'(类型'SplitButton')

XAML

<DataTemplate x:Key="AddNewPartyTemplate">
    <StackPanel HorizontalAlignment="Right" Margin="10">

        <toolkit:SplitButton x:Name="theSplitButton" Content="{resx:Resx Subject_AddNewWithChoices}">
            <toolkit:SplitButton.DropDownContent>
                <StackPanel x:Name="theStackPanel">
                    <Button Content="{resx:Resx Person}" Command="{Binding AddNewPersonCommand}" 
                        >
                        <i:Interaction.Behaviors>
                            <local:CloseDropDownContentBehavior 
                  ***              DropDownButtonElement="{Binding 
                                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type toolkit:SplitButton}}}"/>
                        </i:Interaction.Behaviors>
                    </Button>
                    ...

                </StackPanel>
            </toolkit:SplitButton.DropDownContent>
        </toolkit:SplitButton>
    </StackPanel>
</DataTemplate>

附加行为

public class CloseDropDownContentBehavior : Behavior<ButtonBase>
{
    private ButtonBase _button;

    protected override void OnAttached()
    {
        _button = AssociatedObject;
        _button.Click += OnPartyButtonClick;
    }

    protected override void OnDetaching()
    {
        _button.Click -= OnPartyButtonClick;
    }

    // **** the point of it all
    void OnPartyButtonClick(object sender, RoutedEventArgs e) { DropDownButtonElement.IsOpen = false; }

    public static readonly DependencyProperty DropDownButtonElementProperty =
        DependencyProperty.Register("DropDownButtonElement",
        typeof(SplitButton), typeof(CloseDropDownContentBehavior), new UIPropertyMetadata(null, OnDropDownElementChanged));

    public DropDownButton DropDownButtonElement
    {
        get { return (DropDownButton)GetValue(DropDownButtonElementProperty); }
        set { SetValue(DropDownButtonElementProperty, value); }
    }

    private static void OnDropDownElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {

    }
}

2 个答案:

答案 0 :(得分:1)

猜测是因为Interaction.Behaviors不是视觉树的一部分,所以绑定将找不到祖先。您是否尝试过简单:

DropDownElement="{Binding ElementName=theSplitButton}"

从评论更新:此案例中的解决方案是简单地使用x:Reference

DropDownElement="{x:Reference theSplitButton}"

答案 1 :(得分:0)

我不知道SplitButton.DropDownContent,但如果它的行为类似于上下文菜单,则以下答案可能有所帮助:WPF context menu whose items are defined as data templates

这个技巧是与RelativeSource Self或Type ContextMenu绑定,然后将Path设置为PlacementTarget.DataContext.YourProperty