1

いくつかの DropDownContent とブール値の IsOpen dp を公開して、ドロップダウン コンテンツを表示するかどうかを制御するサード パーティの SplitButton コントロールがあります。

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) です。ターゲット プロパティは '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) {

    }
}
4

2 に答える 2

1

Interaction.Behaviorsがビジュアル ツリーの一部ではないため、バインディングが先祖を見つけられないためだと推測されます。簡単に試しましたか:

DropDownElement="{Binding ElementName=theSplitButton}"

コメントからの更新: この場合の解決策は、単に使用することx:Referenceです:

DropDownElement="{x:Reference theSplitButton}"
于 2012-07-05T12:49:47.443 に答える
0

SplitButton.DropDownContent はわかりませんが、コンテキスト メニューのように動作する場合は、次の回答が役立つ場合があります:項目がデータ テンプレートとして定義されている WPF コンテキスト メニュー

このトリックは、RelativeSource Self または Type ContextMenu とバインドしてから、Path を PlacementTarget.DataContext.YourProperty に設定することです。

于 2012-07-05T13:32:18.017 に答える