Pergunta

Eu tenho um TextBox e um controle Popup. Eu quero a propriedade Popup.IsOpen estar vinculado à propriedade TextBox.IsFocused. Em outras palavras, se a caixa de texto tem o foco, o pop-up é aberto. Alternativamente, se o pop-up está em foco, eu não quero isso para fechar devido ao foco textbox perder. Eu estava esperando para lidar com isso usando ligações ao invés de ter que lidar com isso em manipuladores de eventos. Além disso, eu tenho que fazer alguma coisa a respeito das propriedades de dependência, uma vez que são pré-existente (i. Register, metadados de substituição, etc), ou eu posso apenas ligar a essas propriedades.

Aqui está um código de exemplo semelhante ao meu cenário

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

A partir disso eu estava assumindo que se eu cliquei no controle caixa de texto e deu-lhe concentrar-se, que o pop-up abriria, e, inversamente, se o foco de caixa de texto perdido, que o pop-up iria fechar. Eu não consigo chegar a este trabalho.

Se alguém tem uma idéia do que estou fazendo de errado, então talvez eles poderiam também atender a segunda metade da minha pergunta que, se a caixa de texto perde o foco, mas foi o pop-up que recebe o foco, que o pop-up permanecerá aberta ou dar foco de volta para a caixa de texto para que ele permanecerá bc aberta da ligação em primeiro lugar. Qualquer outro controle que ganha foco quando a caixa de texto perde o foco não se aplica a este cenário.

Se eu pudesse reformular isso para clareza eu diria assim.

1.) Bind Popup.IsOpen para TextBox.IsFocused

2.) Bind TextBox.IsFocused para Popup.IsFocused (assumindo que isso só vai dar foco de volta para a caixa de texto)


Aqui é o meu primeiro C # tentativa neste sentido. Algo ainda não está certo. Nada acontece, então eu não estou muito certo onde meu erro é.

        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;
Foi útil?

Solução

O código a seguir demonstra ter duas caixas de texto em um StackPanel, estabelecendo foco para a caixa de texto superior abrirá o Popup. Em que ponto, se você, em seguida, mover o foco para a caixa de texto contido no Popup permanecerá aberta. Se você mover o foco para outro elemento, neste caso a segunda caixa de texto no StackPanel, o Popup será fechado. Como você não consegue focar o Popup si Estou realmente obrigatório para a propriedade IsFocused da caixa de texto no pop-up.

<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>

Para conseguir a mesma coisa em C # você não tem que usar as ligações elementName como você já tem os elementos na mão direita. Eu quase sempre usar XAML para definir meus elementos para que eu tenho certeza que você poderia arrumar isso um pouco.

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;

Espero que isso ajude!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top