WPF - 交互

  • 简述

    在 WPF 中,交互显示视图如何与位于该视图中的控件进行交互。最常见的相互作用有两种类型 -
    • 行为
    • 拖放
  • 行为

    表达式混合 3 引入了行为,它可以将某些功能封装到可重用的组件中。若要添加其他行为,可以将这些组件附加到控件。行为为轻松设计复杂的用户交互提供了更大的灵活性。
    让我们看一个简单的示例,在该示例中,控件历史记录操作行为附加到控件。
    • 创建一个名为“WPF行为”的新 WPF 项目。
    • 下面的 XAML 代码创建一个椭圆和两个按钮来控制椭圆的移动。
    
    <Window 
       xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:local = "clr-namespace:WPFBehaviors" 
       xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity" 
       xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions" 
       x:Class = "WPFBehaviors.MainWindow" 
       mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
       
       <Window.Resources> 
          <Storyboard x:Key = "Storyboard1" RepeatBehavior = "Forever" AutoReverse = "True"> 
          
             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty =
                "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.X)"
                Storyboard.TargetName = "ellipse"> 
                <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "301.524"/> 
                <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "2.909"/> 
             </DoubleAnimationUsingKeyFrames>
             
             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = 
                "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.Y)"
                Storyboard.TargetName = "ellipse"> 
                <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "-0.485"/> 
                <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "0"/> 
             </DoubleAnimationUsingKeyFrames> 
             
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
                Storyboard.TargetName = "button"> 
                <DiscreteObjectKeyFrame KeyTime = "0" Value = "Play"/> 
             </ObjectAnimationUsingKeyFrames>
             
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
                Storyboard.TargetName = "button1"> 
                <DiscreteObjectKeyFrame KeyTime = "0" Value = "Stop"/> 
                <DiscreteObjectKeyFrame KeyTime = "0:0:2" Value = "Stop"/> 
             </ObjectAnimationUsingKeyFrames> 
          </Storyboard> 
       </Window.Resources> 
       
       <Window.Triggers> 
          <EventTrigger RoutedEvent = "FrameworkElement.Loaded"> 
             <BeginStoryboard Storyboard = "{StaticResource Storyboard1}"/> 
          </EventTrigger> 
       </Window.Triggers> 
       
       <Grid> 
          <Ellipse x:Name = "ellipse" Fill = "#FFAAAAC5" HorizontalMoognment = "Left"
             Height = "50.901" Margin = "49.324,70.922,0,0" Stroke = "Black"
             VerticalMoognment = "Top" Width = "73.684" RenderTransformOrigin = "0.5,0.5"> 
             <Ellipse.RenderTransform> 
                <TransformGroup> 
                   <ScaleTransform/> 
                   <SkewTransform/> 
                   <RotateTransform/> 
                   <TranslateTransform/> 
                </TransformGroup> 
             </Ellipse.RenderTransform> 
          </Ellipse>
          
          <Button x:Name = "button" Content = "Play" HorizontalMoognment = "Left" Height = "24.238"
             Margin = "63.867,0,0,92.953" VerticalMoognment = "Bottom" Width = "74.654"> 
             <i:Interaction.Triggers> 
                <i:EventTrigger EventName = "Click"> 
                   <ei:ControlStoryboardAction Storyboard = "{StaticResource Storyboard1}"/> 
                </i:EventTrigger> 
             </i:Interaction.Triggers> 
          </Button>
          
          <Button x:Name = "button1" Content = "Stop" HorizontalMoognment = "Left" Height = "24.239"
             Margin = "160.82,0,0,93.922" VerticalMoognment = "Bottom" Width = "75.138"> 
             <i:Interaction.Triggers> 
                <i:EventTrigger EventName = "Click"> 
                   <ei:ControlStoryboardAction ControlStoryboardOption = "Stop"
                      Storyboard = "{StaticResource Storyboard1}"/> 
                </i:EventTrigger> 
             </i:Interaction.Triggers> 
          </Button> 
          
       </Grid> 
    </Window>   
    
    编译并执行上述代码时,它将生成以下窗口,其中包含一个椭圆和两个按钮。
    交互输出
    当您按下播放按钮时,它将开始从左向右移动,然后返回到其原始位置。停止按钮将停止椭圆的移动。
    移动已停止
  • 拖放

    在用户界面上拖放可以显著提高应用程序的效率和生产力。很少有应用程序使用拖放功能,因为人们认为它很难实现。在某种程度上,处理拖放功能很困难,但在 WPF 中,您可以非常轻松地处理它。
    让我们举一个简单的例子来了解它是如何工作的。我们将创建一个应用程序,您可以在其中将颜色从一个矩形拖放到另一个矩形。
    • 创建一个名为“WPF”的新 WPF 项目。
    • 将五个矩形拖到设计窗口中,并设置属性,如以下 XAML 文件中所示。
    
    <Window x:Class = "WPFDragAndDrop.MainWindow" 
       xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:local = "clr-namespace:WPFDragAndDrop" 
       mc:Ignorable = "d" Title = "MainWindow" Height = "402.551" Width = "604"> 
       
       <Grid> 
          <Rectangle Name = "Target" Fill = "MooceBlue" HorizontalMoognment = "Left"  
             Height = "345" Margin = "10,10,0,0" Stroke = "Black"  
             VerticalMoognment = "Top" Width = "387" AllowDrop = "True" Drop = "Target_Drop"/> 
             
          <Rectangle Fill = "Beige" HorizontalMoognment = "Left" Height = "65"  
             Margin = "402,10,0,0" Stroke = "Black" VerticalMoognment = "Top"  
             Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
             
          <Rectangle Fill = "LightBlue" HorizontalMoognment = "Left" Height = "65"  
             Margin = "402,80,0,0" Stroke = "Black" VerticalMoognment = "Top"  
             Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
             
          <Rectangle Fill = "LightCoral" HorizontalMoognment = "Left" Height = "65"  
             Margin = "402,150,0,0" Stroke = "Black" VerticalMoognment = "Top"  
             Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
             
          <Rectangle Fill = "LightGray" HorizontalMoognment = "Left" Height = "65"  
             Margin = "402,220,0,0" Stroke = "Black" VerticalMoognment = "Top"  
             Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
             
          <Rectangle Fill = "OliveDrab" HorizontalMoognment = "Left" Height = "65"  
             Margin = "402,290,0,-7" Stroke = "Black" VerticalMoognment = "Top"  
             Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>  
       </Grid> 
       
    </Window> 
    
    • 第一个矩形是目标矩形,因此用户可以将颜色从另一个矩形拖动到目标矩形。
    • 下面给出的是 C# 中用于拖放的事件实现。
    
    using System.Windows; 
    using System.Windows.Input; 
    using System.Windows.Media; 
    using System.Windows.Shapes; 
     
    namespace WPFDragAndDrop { 
       /// <summary> 
          /// Interaction logic for MainWindow.xaml 
       /// </summary> 
       
       public partial class MainWindow : Window { 
       
          public MainWindow() { 
             InitializeComponent(); 
          }  
          
          private void Rect_MLButtonDown(object sender, MouseButtonEventArgs e) { 
             Rectangle rc = sender as Rectangle; 
             DataObject data = new DataObject(rc.Fill); 
             DragDrop.DoDragDrop(rc, data,DragDropEffects.Move); 
          }  
          
          private void Target_Drop(object sender, DragEventArgs e) { 
             SolidColorBrush scb = (SolidColorBrush)e.Data.GetData(typeof(SolidColorBrush)); 
             Target.Fill = scb; 
          } 
       } 
    }
    
    运行应用程序时,它将生成以下窗口。
    拖放颜色
    如果从右侧的矩形拖动颜色并将其放在左侧的大矩形上,您将立即看到它的效果。
    让我们从右侧拖动4个。
    拖放颜色
    您可以看到目标矩形的颜色已更改。我们建议您执行上述代码并尝试其功能。