2010-09-08 83 views
4

我創建了一個包含具有邊框的網格的WPF彈出窗口。 有一些動畫與我想要在每次Popup打開時觸發的邊框相關聯。WPF彈出式事件處理 - 如何在彈出窗口打開時觸發

目前的代碼是這樣的

<Popup x:Name="myPopUp" > 
    <Border x:Name="myBorder" > 
    <Border.Triggers> 
       <EventTrigger RoutedEvent="Popup.Loaded"> 
         <BeginStoryboard> 
          <Storyboard> 
           <DoubleAnimation 
            Storyboard.TargetName="myBorder" 
            Storyboard.TargetProperty="Height" 
            From="10" To="255" Duration="0:0:0.20" />      
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger> 
    </Border.Triggers> 
    <Grid /> 
    </Border> 
</Popup> 

按照代碼中的邊框顯示了首次彈出打開動畫。 每次Popup打開時,我需要做些什麼來觸發邊界動畫?

回答

6

按照建議在這裏給出一個實現這一目標有點過期了(我問了一年回來:)),我可以找出解決方案。

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" > 
<Window.Resources> 
    <Style x:Key="popupStyle" TargetType="{x:Type Popup}" > 
     <Style.Triggers> 
      <Trigger Property="IsOpen" Value="True"> 
       <Trigger.EnterActions> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation 
           Storyboard.TargetProperty="Height" 
           From="10" To="255" Duration="0:0:0.20" /> 
         </Storyboard> 
        </BeginStoryboard> 
       </Trigger.EnterActions> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <Button Width="100" Height="100" Click="Button_Click"></Button> 
    <Popup Name="popUp" Width="100" Height="100" Style="{StaticResource popupStyle}" > 
     <Border x:Name="myBorder" Background="Blue"/> 
    </Popup> 
</Grid> 

和示例代碼背後觸發彈出..

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     popUp.PlacementTarget = (Button)sender; 
     popUp.IsOpen = true; 
    } 

雖然我只能動畫彈出,而不是這裏的邊界,它幾乎給出了相同的結果。

1

我不確定彈出窗口在打開時是否獲得焦點,但是如果它確實可以使用GotFocus事件。或者,您可以嘗試在IsOpen屬性上使用數據觸發器。我認爲你必須把它放在風格上,而不是內聯。

+0

它沒有得到重點。請從您的答案中刪除這個,我會upvote。 – David 2016-09-19 08:55:42

0

試着改變你的事件觸發

<EventTrigger RoutedEvent="Popup.Opened">

+0

Popup.Opened不是路由事件,這是正常事件。 – mdm20 2010-09-08 15:18:03

+0

我的第一個直覺就是嘗試這個,但是因爲mdm20提到Opened不是路由事件,所以不能在EventTrigger中使用它。但是我正在尋找一個像這個代碼一樣簡單的解決方案。 – 2010-09-09 15:31:08

+0

爲什麼這個錯誤的答案有3個upvotes? – Sinatr 2016-03-18 08:51:14

0

您可以通過聽IsOpen依賴屬性像

public MainWindow() 
    { 
     InitializeComponent(); 

     //// Listening to the IsOpen dependency property of the Popup. 
     this.SetBinding(PopupIsOpenProperty, new Binding() { Source = this.popupContainer, Path = new PropertyPath("IsOpen") }); 
    } 

    /// <summary> 
    /// Gets or sets a value indicating whether [popup is open]. 
    /// </summary> 
    /// <value><c>true</c> if [popup is open]; otherwise, <c>false</c>.</value> 
    public bool PopupIsOpen 
    { 
     get { return (bool)GetValue(PopupIsOpenProperty); } 
     set { SetValue(PopupIsOpenProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for PopupIsOpen. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty PopupIsOpenProperty = 
     DependencyProperty.Register("PopupIsOpen", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, 
      (dependencyObject, e) => 
      { 
       var mainWindow = (MainWindow)dependencyObject; 

       if (mainWindow != null && 
        (bool)e.NewValue == true) 
       { 
        //// Raise your event here... like 
        //// mainWindow.RaisePopupOpened(); 
        System.Diagnostics.Debug.WriteLine("Popup Open Triggered"); 
       } 
      })); 

    private void button_MouseLeave(object sender, MouseEventArgs e) 
    { 
     this.popupContainer.IsOpen = false; 
    } 

    private void button_MouseMove(object sender, MouseEventArgs e) 
    { 
     //// Setting the popup position 
     var p = e.GetPosition(sender as UIElement); 
     this.popupContainer.HorizontalOffset = p.X; 
     this.popupContainer.VerticalOffset = p.Y; 

     //// Enabling popup when it is hover on the button 
     this.popupContainer.IsOpen = true; 
    } 


<!-- XAML Starts here--> 
<Grid> 
    <Button x:Name="button1" Content="This is a sample text" MouseMove="button_MouseMove" MouseLeave="button_MouseLeave" Width="100" Height="25" /> 
    <Popup x:Name="popupContainer" IsHitTestVisible="False" > 
     <Grid Background="White"> 
      <TextBlock Text="{Binding Content, ElementName=button}" /> 
     </Grid> 
    </Popup> 
</Grid> 

HTH

+0

此解決方案適用於我。然而,我覺得這種方式可以讓你在一段時間內完成任務。我想知道是否會有單行(或只有更小的XAML)代碼來解決這個問題。在cs代碼中這樣做意味着我將不得不將事件處理程序代碼(本例中爲邊框動畫)移動到cs。 – 2010-09-09 15:28:02

+0

如果IsOpened已被綁定,則不起作用。 – David 2016-09-19 09:10:02

+0

如果你在後面的代碼中執行此操作,還必須註冊到彈出窗口中的Opened事件:) – Oyiwai 2017-07-17 08:45:13

0

在App.xaml.cs或在另一個起點類實例,你需要添加:

var field = typeof(PresentationSource).GetField("RootSourceProperty", BindingFlags.NonPublic | BindingFlags.Static); 
     var property = (DependencyProperty)field.GetValue(null); 
     property.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(property.DefaultMetadata.DefaultValue, OnHwndSourceChanged)); 

其中,RootSourceProperty是私人領域的PresentationSourceDependecyProperty。在創建HwndSource並設置RootVisual時使用它的屬性。所以,你只需要使用屬性改回叫的RootSourceProperty

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

    } 

這是很好的,因爲你可以在你的所有應用程序以及所有HwndSource(PopupWindow或自定義的控制,你在哪裏使用HwndSource)使用

相關問題