3

私はTextBoxPopupコントロールを持っています。Popup.IsOpenプロパティをプロパティにバインドしたいTextBox.IsFocused。つまり、テキスト ボックスにフォーカスがある場合、ポップアップが開いています。または、ポップアップにフォーカスがある場合、テキストボックスがフォーカスを失ったためにポップアップを閉じたくありません。イベントハンドラーでこれを処理するのではなく、バインディングを使用してこれを処理することを望んでいました。また、依存関係プロパティは既存のもの (つまり、登録、メタデータのオーバーライドなど) であるため、依存関係プロパティに関して何かを行う必要がありますか、またはこれらのプロパティにバインドするだけでよいでしょうか。

これが私のシナリオに似たサンプルコードです

StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
Popup popup = new Popup();

sp.Children.Add(tb);
sp.Children.Add(popup);
this.Content = sp;

Binding bd = new Binding("IsFocused");
bd.source = tb.IsFocused;
popup.SetBinding(Popup.IsOpenProperty, bd);

このことから、テキスト ボックス コントロールをクリックしてフォーカスを与えるとポップアップが開き、逆にテキスト ボックスがフォーカスを失うとポップアップが閉じると想定していました。私はこれを機能させることができないようです。

誰かが私が間違っていることを知っている場合、テキストボックスがフォーカスを失ったがフォーカスを受け取ったのはポップアップだった場合、ポップアップが開いたままになるか、フォーカスを戻すという私の質問の後半にも答えることができるかもしれません最初のバインディングの前に開いたままになるように、テキストボックスに追加します。テキスト ボックスがフォーカスを失ったときにフォーカスを取得するその他のコントロールは、このシナリオには適用されません。

わかりやすくするためにこれを言い換えることができるとしたら、私はこのように言います。

1.)バインドPopup.IsOpenするTextBox.IsFocused

2.)にバインドTextBox.IsFocusedPopup.IsFocusedます (これにより、フォーカスがテキスト ボックスに戻されると仮定します) 。


これが私の最初のC#の試みです。何かがまだ正しくありません。何も起こらないので、どこが間違っているのかよくわかりません。

        StackPanel sp = new StackPanel(); 
        TextBox tb = new TextBox(); 
        Popup popup = new Popup();

        TextBox popupTextBox = new TextBox();
        popup.Child = popupTextBox;


        sp.Children.Add(tb); 
        sp.Children.Add(popup); 
        this.Content = sp;


        //***Questions concerning giving the UIElement a name and registering it
        tb.Name = "siblingTextBox";
        System.Windows.NameScope.GetNameScope(tb).RegisterName("siblingTextBox", tb);

        //***Questions concerning giving the UIElement a name and registering it
        popupTextBox.Name = "popupTextBox";
        System.Windows.NameScope.GetNameScope(tb).RegisterName("popupTextBox", popupTextBox);

        Binding binding = new Binding();
        binding.ElementName = tb.Name;
        popup.PlacementTarget = tb;

        Style style = new Style();
        style.TargetType = typeof(Popup);

        DataTrigger dataTrigger = new DataTrigger();
        Binding focusedBinding = new Binding("IsFocused");
        focusedBinding.ElementName = tb.Name;
        dataTrigger.Value = true;
        dataTrigger.Binding = focusedBinding;

        Setter setter = new Setter();
        setter.Property = Popup.IsOpenProperty;
        setter.Value = true;
        dataTrigger.Setters.Add(setter);
        style.Triggers.Add(dataTrigger);

        dataTrigger = new DataTrigger();
        focusedBinding = new Binding("IsFocused");
        focusedBinding.ElementName = popupTextBox.Name;
        dataTrigger.Value = true;
        dataTrigger.Binding = focusedBinding;
        setter = new Setter();
        setter.Property = Popup.IsOpenProperty;
        setter.Value = true;
        dataTrigger.Setters.Add(setter);
        style.Triggers.Add(dataTrigger);

        popup.Style = style;
4

1 に答える 1

4

次のコードは、StackPanel に 2 つのテキスト ボックスがあることを示しています。一番上のテキスト ボックスにフォーカスを設定すると、ポップアップが開きます。その時点で、フォーカスをポップアップに含まれるテキスト ボックスに移動すると、開いたままになります。フォーカスを別の要素 (この例では StackPanel の 2 番目のテキスト ボックス) に移動すると、Popup が閉じます。ポップアップ自体にフォーカスを当てることができないため、実際にはポップアップのテキスト ボックスの IsFocused プロパティにバインドしています。

<StackPanel>
    <TextBox x:Name="text" Text="This is a text box" />
    <TextBox Text="Another Text Box" />
    <Popup PlacementTarget="{Binding ElementName=text}">
        <Popup.Style>
            <Style TargetType="{x:Type Popup}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=text, Path=IsFocused}" Value="True">
                        <Setter Property="IsOpen" Value="True" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding ElementName=popupText, Path=IsFocused}" Value="True">
                        <Setter Property="IsOpen" Value="True" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Popup.Style>
        <TextBox x:Name="popupText" Text="HELLO WORLD" />
    </Popup>
</StackPanel>

C# で同じことを実現するために、ElementName バインディングを使用する必要はありません。要素は既に手元にあるからです。私はほとんどの場合、XAML を使用して要素を定義しているので、これを少し整理できると確信しています。

var text1 = new TextBox { Name = "text", Text = "This is a text box" };
var text2 = new TextBox { Text = "Another Text Box" };
var popupText = new TextBox { Name = "popupText", Text = "HELLO WORLD" };
var popup = new Popup { Child = popupText, PlacementTarget = text1 };
var stackPanel = new StackPanel();

stackPanel.Children.Add(text1);
stackPanel.Children.Add(text2);
stackPanel.Children.Add(popup);

var popupStyle = new Style(typeof (Popup));
var textIsFocusedTrigger = new DataTrigger
    {
        Binding = new Binding {Source = text1, Path = new PropertyPath("IsFocused")},
        Value = true
    };

textIsFocusedTrigger.Setters.Add(new Setter(Popup.IsOpenProperty, true));

var popupTextIsFocusedTrigger = new DataTrigger
    {
        Binding = new Binding {Source = popupText, Path = new PropertyPath("IsFocused")},
        Value = true
    };

popupTextIsFocusedTrigger.Setters.Add(new Setter(Popup.IsOpenProperty, true));

popupStyle.Triggers.Add(textIsFocusedTrigger);
popupStyle.Triggers.Add(popupTextIsFocusedTrigger);

popup.Style = popupStyle;

これが役立つことを願っています!

于 2009-05-18T19:19:32.603 に答える