2016-10-04 2 views
1

У меня есть ContentControl со стилем, который содержит всплывающее окно, которое обертывает текстовое поле. Я знаю, это звучит немного запутанно, но я отправлю код ниже. Когда отображается клавиша блокировки колпачка, отображается всплывающее окно, но когда окно перетаскивается, всплывающее окно не перемещается вместе с ним.Popup в стиле ContentControl не обновляется

Мне нужно выяснить, как обновить местоположение всплывающего окна в их стиле.

Этот ContentControl используется как в окне, так и в UserControl, поэтому я пытаюсь обратиться к этому в стиле.

Этот вопрос отличается от некоторых других, поскольку я пытаюсь решить его в стиле, а не в коде.

Контроль содержания:

public class ShowCapLockWarningControler : ContentControl 
{ 

    static ShowCapLockWarningControler() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ShowCapLockWarningControler), new FrameworkPropertyMetadata(typeof(ShowCapLockWarningControler))); 
    } 

    public static readonly DependencyProperty ShowMessageProperty = 
     DependencyProperty.Register(Reflection.GetPropertyName<ShowCapLockWarningControler>(i => i.ShowMessage), typeof(bool), 
            typeof(ShowCapLockWarningControler), new PropertyMetadata(false)); 

    public bool ShowMessage 
    { 
     get { return (bool)GetValue(ShowMessageProperty); } 
     set { SetValue(ShowMessageProperty, value); } 
    } 

    public ShowCapLockWarningControler() 
    { 
     IsKeyboardFocusWithinChanged += (s, e) => RecomputeShowMessage(); 
     PreviewKeyDown += (s, e) => RecomputeShowMessage(); 
     PreviewKeyUp += (s, e) => RecomputeShowMessage(); 
    } 

    private void RecomputeShowMessage() 
    { 
     ShowMessage = IsKeyboardFocusWithin && Console.CapsLock; 
    } 
} 

Как его использовали:

<controls:ShowCapLockWarningControler Grid.Row="1" Grid.Column="2" Style="{DynamicResource CaplockWarning}"> 
    <PasswordBox Width="150" Name="PasswordBox" PasswordChanged="HandlePasswordChanged" VerticalContentAlignment="Center" 
       KeyDown="HandlePasswordBoxEnterPressed"/> 
</controls:ShowCapLockWarningControler> 

Стиль в словаре стиль:

<Style x:Key="CaplockWarning" TargetType="{x:Type controls:ShowCapLockWarningControler}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type controls:ShowCapLockWarningControler}"> 
       <Grid> 
        <ContentPresenter Name="Presenter"/> 
        <Popup Placement="Bottom" PlacementTarget="{Binding ElementName=Presenter}" Name="BalloonPopup" AllowsTransparency="True" 
          IsOpen="{TemplateBinding ShowMessage}" > 
         <!-- Visual of the popup-->      
        </Popup> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
+0

Я ищу, чтобы заботиться об этом в стиле, потому что нет места, чтобы добавить код позади и привязок. –

+0

Почему вы сохраняете всплывающее окно. Закройте его на потерянном фокусе. – Versatile

ответ

0

Использование Window.LocationChanged event, Popup.Placement = AbsolutePoint, Popup.HorizontalOffset, Popup.VerticalOffset.

В приведенном ниже примере Popup появляется, когда ContentControl'sLoaded Событие увольняется. И мы меняем соответствующие свойства Popup, когда Window меняет свое местоположение.

Код:

<ContentControl x:Name="CntCtrl" Height="35" Content="Some content" Loaded="CntCtrl_Loaded_1"/> 

<Popup PlacementTarget="{Binding ElementName=CntCtrl}" Placement="AbsolutePoint" x:Name="Popup1"> 
    <ListBox> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
     <ListBoxItem>item1</ListBoxItem> 
    </ListBox> 
</Popup> 

Код:

private void Window_LocationChanged_1(object sender, EventArgs e) 
{   
    Point ptb = CntCtrl.PointToScreen(new Point(0, 0)); 
    Popup1.HorizontalOffset = ptb.X; 
    Popup1.VerticalOffset = ptb.Y + CntCtrl.Height; 
} 

private void CntCtrl_Loaded_1(object sender, RoutedEventArgs e) 
{ 
    Popup1.IsOpen = true; 
    Point ptb = CntCtrl.PointToScreen(new Point(0, 0)); 
    Popup1.HorizontalOffset = ptb.X; 
    Popup1.VerticalOffset = ptb.Y + CntCtrl.Height; 
} 
+0

Его не совсем в стиле, но он будет делать. Спасибо. –

Смежные вопросы